GCC Code Coverage Report


Directory: ./
File: sql/sql_base.cc
Date: 2022-11-26 14:12:44
Exec Total Coverage
Lines: 3303 3564 92.7%
Branches: 4119 6294 65.4%

Line Branch Exec Source
1 /* Copyright (c) 2000, 2022, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 /* Basic functions needed by many modules */
24
25 #include "sql/sql_base.h"
26
27 #include <fcntl.h>
28 #include <limits.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <time.h>
32 #include <atomic>
33 #include <functional>
34 #include <memory>
35 #include <unordered_map>
36 #include <utility>
37
38 #include "ft_global.h"
39 #include "libbinlogevents/include/table_id.h"
40 #include "m_ctype.h"
41 #include "m_string.h"
42 #include "map_helpers.h"
43 #include "mf_wcomp.h" // wild_one, wild_many
44 #include "mutex_lock.h"
45 #include "my_alloc.h"
46 #include "my_bitmap.h"
47 #include "my_byteorder.h"
48 #include "my_compiler.h"
49 #include "my_dbug.h"
50 #include "my_dir.h"
51 #include "my_io.h"
52 #include "my_loglevel.h"
53 #include "my_macros.h"
54 #include "my_psi_config.h"
55 #include "my_sqlcommand.h"
56 #include "my_sys.h"
57 #include "my_systime.h"
58 #include "my_table_map.h"
59 #include "my_thread_local.h"
60 #include "mysql/components/services/bits/mysql_cond_bits.h"
61 #include "mysql/components/services/bits/psi_bits.h"
62 #include "mysql/components/services/bits/psi_cond_bits.h"
63 #include "mysql/components/services/bits/psi_mutex_bits.h"
64 #include "mysql/components/services/log_builtins.h"
65 #include "mysql/plugin.h"
66 #include "mysql/psi/mysql_cond.h"
67 #include "mysql/psi/mysql_file.h"
68 #include "mysql/psi/mysql_mutex.h"
69 #include "mysql/psi/mysql_statement.h"
70 #include "mysql/psi/mysql_table.h"
71 #include "mysql/psi/mysql_thread.h"
72 #include "mysql/psi/psi_table.h"
73 #include "mysql/service_mysql_alloc.h"
74 #include "mysql/thread_type.h"
75 #include "mysql_com.h"
76 #include "mysqld_error.h"
77 #include "sql/auth/auth_acls.h"
78 #include "sql/auth/auth_common.h" // check_table_access
79 #include "sql/auth/sql_security_ctx.h"
80 #include "sql/binlog.h" // mysql_bin_log
81 #include "sql/check_stack.h"
82 #include "sql/dd/cache/dictionary_client.h"
83 #include "sql/dd/dd.h" // dd::get_dictionary()
84 #include "sql/dd/dd_schema.h"
85 #include "sql/dd/dd_table.h" // dd::table_exists
86 #include "sql/dd/dd_tablespace.h" // dd::fill_table_and_parts_tablespace_name
87 #include "sql/dd/dictionary.h"
88 #include "sql/dd/string_type.h"
89 #include "sql/dd/types/abstract_table.h"
90 #include "sql/dd/types/column.h"
91 #include "sql/dd/types/column_statistics.h"
92 #include "sql/dd/types/foreign_key.h" // dd::Foreign_key
93 #include "sql/dd/types/function.h"
94 #include "sql/dd/types/procedure.h"
95 #include "sql/dd/types/schema.h"
96 #include "sql/dd/types/table.h" // dd::Table
97 #include "sql/dd/types/view.h"
98 #include "sql/dd_table_share.h" // open_table_def
99 #include "sql/debug_sync.h" // DEBUG_SYNC
100 #include "sql/derror.h" // ER_THD
101 #include "sql/error_handler.h" // Internal_error_handler
102 #include "sql/field.h"
103 #include "sql/handler.h"
104 #include "sql/histograms/histogram.h"
105 #include "sql/item.h"
106 #include "sql/item_cmpfunc.h" // Item_func_eq
107 #include "sql/item_func.h"
108 #include "sql/item_subselect.h"
109 #include "sql/lock.h" // mysql_lock_remove
110 #include "sql/log.h"
111 #include "sql/log_event.h" // Query_log_event
112 #include "sql/mysqld.h" // replica_open_temp_tables
113 #include "sql/mysqld_thd_manager.h" // Global_THD_manage
114 #include "sql/nested_join.h"
115 #include "sql/partition_info.h" // partition_info
116 #include "sql/psi_memory_key.h" // key_memory_TABLE
117 #include "sql/query_options.h"
118 #include "sql/rpl_gtid.h"
119 #include "sql/rpl_handler.h" // RUN_HOOK
120 #include "sql/rpl_replica_commit_order_manager.h" // has_commit_order_manager
121 #include "sql/rpl_rli.h" //Relay_log_information
122 #include "sql/session_tracker.h"
123 #include "sql/sp.h" // Sroutine_hash_entry
124 #include "sql/sp_cache.h" // sp_cache_version
125 #include "sql/sp_head.h" // sp_head
126 #include "sql/sql_audit.h" // mysql_audit_table_access_notify
127 #include "sql/sql_backup_lock.h" // acquire_shared_backup_lock
128 #include "sql/sql_class.h" // THD
129 #include "sql/sql_const.h"
130 #include "sql/sql_data_change.h"
131 #include "sql/sql_db.h" // check_schema_readonly
132 #include "sql/sql_error.h" // Sql_condition
133 #include "sql/sql_handler.h" // mysql_ha_flush_tables
134 #include "sql/sql_lex.h"
135 #include "sql/sql_list.h"
136 #include "sql/sql_parse.h" // is_update_query
137 #include "sql/sql_prepare.h" // Reprepare_observer
138 #include "sql/sql_select.h" // reset_statement_timer
139 #include "sql/sql_show.h" // append_identifier
140 #include "sql/sql_sort.h"
141 #include "sql/sql_table.h" // build_table_filename
142 #include "sql/sql_update.h" // records_are_comparable
143 #include "sql/sql_view.h" // mysql_make_view
144 #include "sql/strfunc.h"
145 #include "sql/system_variables.h"
146 #include "sql/table.h" // TABLE_LIST
147 #include "sql/table_cache.h" // table_cache_manager
148 #include "sql/table_trigger_dispatcher.h" // Table_trigger_dispatcher
149 #include "sql/thd_raii.h"
150 #include "sql/transaction.h" // trans_rollback_stmt
151 #include "sql/transaction_info.h"
152 #include "sql/trigger_chain.h" // Trigger_chain
153 #include "sql/xa.h"
154 #include "sql_string.h"
155 #include "template_utils.h"
156 #include "thr_mutex.h"
157
158 using std::equal_to;
159 using std::hash;
160 using std::pair;
161 using std::string;
162 using std::unique_ptr;
163 using std::unordered_map;
164
165 /**
166 The maximum length of a key in the table definition cache.
167
168 The key consists of the schema name, a '\0' character, the table
169 name and a '\0' character. Hence NAME_LEN * 2 + 1 + 1.
170
171 Additionally, the key can be suffixed with either 4 + 4 extra bytes
172 for slave tmp tables, or with a single extra byte for tables in a
173 secondary storage engine. Add 4 + 4 to account for either of these
174 suffixes.
175 */
176 static constexpr const size_t MAX_DBKEY_LENGTH{NAME_LEN * 2 + 1 + 1 + 4 + 4};
177
178 static constexpr long STACK_MIN_SIZE_FOR_OPEN{1024 * 80};
179
180 /**
181 This internal handler is used to trap ER_NO_SUCH_TABLE and
182 ER_WRONG_MRG_TABLE errors during CHECK/REPAIR TABLE for MERGE
183 tables.
184 */
185
186 class Repair_mrg_table_error_handler : public Internal_error_handler {
187 public:
188 2 Repair_mrg_table_error_handler()
189 2 : m_handled_errors(false), m_unhandled_errors(false) {}
190
191 1 bool handle_condition(THD *, uint sql_errno, const char *,
192 Sql_condition::enum_severity_level *,
193 const char *) override {
194
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if (sql_errno == ER_NO_SUCH_TABLE || sql_errno == ER_WRONG_MRG_TABLE) {
195 1 m_handled_errors = true;
196 1 return true;
197 }
198
199 m_unhandled_errors = true;
200 return false;
201 }
202
203 /**
204 Returns true if there were ER_NO_SUCH_/WRONG_MRG_TABLE and there
205 were no unhandled errors. false otherwise.
206 */
207 2 bool safely_trapped_errors() {
208 /*
209 Check for m_handled_errors is here for extra safety.
210 It can be useful in situation when call to open_table()
211 fails because some error which was suppressed by another
212 error handler (e.g. in case of MDL deadlock which we
213 decided to solve by back-off and retry).
214 */
215
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 return (m_handled_errors && (!m_unhandled_errors));
216 }
217
218 private:
219 bool m_handled_errors;
220 bool m_unhandled_errors;
221 };
222
223 /**
224 @defgroup Data_Dictionary Data Dictionary
225 @{
226 */
227
228 /**
229 LOCK_open protects the following variables/objects:
230
231 1) The table_def_cache
232 This is the hash table mapping table name to a table
233 share object. The hash table can only be manipulated
234 while holding LOCK_open.
235 2) last_table_id
236 Generation of a new unique table_map_id for a table
237 share is done through incrementing last_table_id, a
238 global variable used for this purpose.
239 3) LOCK_open protects the initialisation of the table share
240 object and all its members, however, it does not protect
241 reading the .frm file from where the table share is
242 initialised. In get_table_share, the lock is temporarily
243 released while opening the table definition in order to
244 allow a higher degree of concurrency. Concurrent access
245 to the same share is controlled by introducing a condition
246 variable for signaling when opening the share is completed.
247 4) In particular the share->ref_count is updated each time
248 a new table object is created that refers to a table share.
249 This update is protected by LOCK_open.
250 5) oldest_unused_share, end_of_unused_share and share->next
251 and share->prev are variables to handle the lists of table
252 share objects, these can only be read and manipulated while
253 holding the LOCK_open mutex.
254 6) table_def_shutdown_in_progress can be updated only while
255 holding LOCK_open and ALL table cache mutexes.
256 7) refresh_version
257 This variable can only be updated while holding LOCK_open AND
258 all table cache mutexes.
259 8) share->version
260 This variable is initialised while holding LOCK_open. It can only
261 be updated while holding LOCK_open AND all table cache mutexes.
262 So if a table share is found through a reference its version won't
263 change if any of those mutexes are held.
264 9) share->m_flush_tickets
265 */
266
267 mysql_mutex_t LOCK_open;
268
269 /**
270 COND_open synchronizes concurrent opening of the same share:
271
272 If a thread calls get_table_share, it releases the LOCK_open
273 mutex while reading the definition from file. If a different
274 thread calls get_table_share for the same share at this point
275 in time, it will find the share in the TDC, but with the
276 m_open_in_progress flag set to true. This will make the
277 (second) thread wait for the COND_open condition, while the
278 first thread completes opening the table definition.
279
280 When the first thread is done reading the table definition,
281 it will set m_open_in_progress to false and broadcast the
282 COND_open condition. Then, all threads waiting for COND_open
283 will wake up and, re-search the TDC for the share, and:
284
285 1) If the share is gone, the thread will continue to allocate
286 and open the table definition. This happens, e.g., if the
287 first thread failed when opening the table definition and
288 had to destroy the share.
289 2) If the share is still in the cache, and m_open_in_progress
290 is still true, the thread will wait for the condition again.
291 This happens if a different thread finished opening a
292 different share.
293 3) If the share is still in the cache, and m_open_in_progress
294 has become false, the thread will check if the share is ok
295 (no error), increment the ref counter, and return the share.
296 */
297
298 mysql_cond_t COND_open;
299
300 #ifdef HAVE_PSI_INTERFACE
301 static PSI_mutex_key key_LOCK_open;
302 static PSI_cond_key key_COND_open;
303 static PSI_mutex_info all_tdc_mutexes[] = {
304 {&key_LOCK_open, "LOCK_open", PSI_FLAG_SINGLETON, 0, PSI_DOCUMENT_ME}};
305 static PSI_cond_info all_tdc_conds[] = {
306 {&key_COND_open, "COND_open", 0, 0, PSI_DOCUMENT_ME}};
307
308 /**
309 Initialize performance schema instrumentation points
310 used by the table cache.
311 */
312
313 12112 static void init_tdc_psi_keys(void) {
314 12112 const char *category = "sql";
315 int count;
316
317 12112 count = static_cast<int>(array_elements(all_tdc_mutexes));
318 12112 mysql_mutex_register(category, all_tdc_mutexes, count);
319
320 12112 count = static_cast<int>(array_elements(all_tdc_conds));
321 12112 mysql_cond_register(category, all_tdc_conds, count);
322 12112 }
323 #endif /* HAVE_PSI_INTERFACE */
324
325 using Table_definition_cache =
326 malloc_unordered_map<std::string,
327 std::unique_ptr<TABLE_SHARE, Table_share_deleter>>;
328 Table_definition_cache *table_def_cache;
329 static TABLE_SHARE *oldest_unused_share, end_of_unused_share;
330 static bool table_def_shutdown_in_progress = false;
331
332 static bool check_and_update_table_version(THD *thd, TABLE_LIST *tables,
333 TABLE_SHARE *table_share);
334 static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share,
335 const dd::Table *table, TABLE *entry);
336 static bool auto_repair_table(THD *thd, TABLE_LIST *table_list);
337 static TABLE *find_temporary_table(THD *thd, const char *table_key,
338 size_t table_key_length);
339 static bool tdc_open_view(THD *thd, TABLE_LIST *table_list,
340 const char *cache_key, size_t cache_key_length);
341 static bool add_view_place_holder(THD *thd, TABLE_LIST *table_list);
342
343 /**
344 Create a table cache/table definition cache key for a table. The
345 table is neither a temporary table nor a table in a secondary
346 storage engine.
347
348 @note
349 The table cache_key is created from:
350
351 db_name + \0
352 table_name + \0
353
354 @param[in] db_name the database name
355 @param[in] table_name the table name
356 @param[out] key buffer for the key to be created (must be of
357 size MAX_DBKEY_LENGTH)
358 @return the length of the key
359 */
360 4358051 static size_t create_table_def_key(const char *db_name, const char *table_name,
361 char *key) {
362 /*
363 In theory caller should ensure that both db and table_name are
364 not longer than NAME_LEN bytes. In practice we play safe to avoid
365 buffer overruns.
366 */
367
2/4
✓ Branch 0 taken 4358051 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4358051 times.
✗ Branch 3 not taken.
4358051 assert(strlen(db_name) <= NAME_LEN && strlen(table_name) <= NAME_LEN);
368 4358051 return strmake(strmake(key, db_name, NAME_LEN) + 1, table_name, NAME_LEN) -
369 4358051 key + 1;
370 }
371
372 /**
373 Create a table cache/table definition cache key for a temporary table.
374
375 The key is constructed by appending the following to the key
376 generated by #create_table_def_key():
377
378 - 4 bytes for master thread id
379 - 4 bytes pseudo thread id
380
381 @param[in] thd thread context
382 @param[in] db_name the database name
383 @param[in] table_name the table name
384 @param[out] key buffer for the key to be created (must be of
385 size MAX_DBKEY_LENGTH)
386 @return the length of the key
387 */
388 325832 static size_t create_table_def_key_tmp(const THD *thd, const char *db_name,
389 const char *table_name, char *key) {
390 325832 size_t key_length = create_table_def_key(db_name, table_name, key);
391 325832 int4store(key + key_length, thd->server_id);
392 325832 int4store(key + key_length + 4, thd->variables.pseudo_thread_id);
393 325832 return key_length + TMP_TABLE_KEY_EXTRA;
394 }
395
396 /**
397 Create a table cache/table definition cache key for a table in a
398 secondary storage engine.
399
400 The key is constructed by appending a single byte with the value 1
401 to the key generated by #create_table_def_key().
402
403 @param db_name the database name
404 @param table_name the table name
405 @return the key
406 */
407 1563369 static std::string create_table_def_key_secondary(const char *db_name,
408 const char *table_name) {
409 char key[MAX_DBKEY_LENGTH];
410
1/2
✓ Branch 0 taken 1563369 times.
✗ Branch 1 not taken.
1563369 size_t key_length = create_table_def_key(db_name, table_name, key);
411 // Add a single byte to distinguish the secondary table from the
412 // primary table. Their db name and table name are identical.
413 1563369 key[key_length++] = 1;
414
1/2
✓ Branch 0 taken 1563369 times.
✗ Branch 1 not taken.
1563369 return {key, key_length};
415 }
416
417 /**
418 Get table cache key for a table list element.
419
420 @param [in] table_list Table list element.
421 @param [out] key On return points to table cache key for the table.
422
423 @note Unlike create_table_def_key() call this function doesn't construct
424 key in a buffer provider by caller. Instead it relies on the fact
425 that table list element for which key is requested has properly
426 initialized MDL_request object and the fact that table definition
427 cache key is suffix of key used in MDL subsystem. So to get table
428 definition key it simply needs to return pointer to appropriate
429 part of MDL_key object nested in this table list element.
430 Indeed, this means that lifetime of key produced by this call is
431 limited by the lifetime of table list element which it got as
432 parameter.
433
434 @return Length of key.
435 */
436
437 137294730 size_t get_table_def_key(const TABLE_LIST *table_list, const char **key) {
438 /*
439 This call relies on the fact that TABLE_LIST::mdl_request::key object
440 is properly initialized, so table definition cache can be produced
441 from key used by MDL subsystem.
442 strcase is converted to strcasecmp because information_schema tables
443 can be accessed with lower case and upper case table names.
444 */
445
3/4
✓ Branch 0 taken 137296282 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 137296356 times.
✓ Branch 3 taken 18 times.
137294730 assert(!my_strcasecmp(system_charset_info, table_list->get_db_name(),
446 table_list->mdl_request.key.db_name()) &&
447 !my_strcasecmp(system_charset_info, table_list->get_table_name(),
448 table_list->mdl_request.key.name()));
449
450 137296356 *key = (const char *)table_list->mdl_request.key.ptr() + 1;
451 137296177 return table_list->mdl_request.key.length() - 1;
452 }
453
454 /*****************************************************************************
455 Functions to handle table definition cache (TABLE_SHARE)
456 *****************************************************************************/
457
458 2227707 void Table_share_deleter::operator()(TABLE_SHARE *share) const {
459
1/2
✓ Branch 0 taken 2227707 times.
✗ Branch 1 not taken.
2227707 DBUG_TRACE;
460 2227707 mysql_mutex_assert_owner(&LOCK_open);
461
2/2
✓ Branch 0 taken 304513 times.
✓ Branch 1 taken 1923194 times.
2227707 if (share->prev) {
462 /* remove from old_unused_share list */
463 304513 *share->prev = share->next;
464 304513 share->next->prev = share->prev;
465 }
466
1/2
✓ Branch 0 taken 2227707 times.
✗ Branch 1 not taken.
2227707 free_table_share(share);
467 2227707 }
468
469 12112 bool table_def_init(void) {
470 #ifdef HAVE_PSI_INTERFACE
471 12112 init_tdc_psi_keys();
472 #endif
473 12112 mysql_mutex_init(key_LOCK_open, &LOCK_open, MY_MUTEX_INIT_FAST);
474 12112 mysql_cond_init(key_COND_open, &COND_open);
475 12112 oldest_unused_share = &end_of_unused_share;
476 12112 end_of_unused_share.prev = &oldest_unused_share;
477
478
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12112 times.
12112 if (table_cache_manager.init()) {
479 mysql_cond_destroy(&COND_open);
480 mysql_mutex_destroy(&LOCK_open);
481 return true;
482 }
483
484
1/2
✓ Branch 0 taken 12112 times.
✗ Branch 1 not taken.
12112 table_def_cache = new Table_definition_cache(key_memory_table_share);
485 12112 return false;
486 }
487
488 /**
489 Notify table definition cache that process of shutting down server
490 has started so it has to keep number of TABLE and TABLE_SHARE objects
491 minimal in order to reduce number of references to pluggable engines.
492 */
493
494 10491 void table_def_start_shutdown(void) {
495
2/2
✓ Branch 0 taken 10440 times.
✓ Branch 1 taken 51 times.
10491 if (table_def_cache != nullptr) {
496 10440 table_cache_manager.lock_all_and_tdc();
497 /*
498 Ensure that TABLE and TABLE_SHARE objects which are created for
499 tables that are open during process of plugins' shutdown are
500 immediately released. This keeps number of references to engine
501 plugins minimal and allows shutdown to proceed smoothly.
502 */
503 10440 table_def_shutdown_in_progress = true;
504 10440 table_cache_manager.unlock_all_and_tdc();
505 /* Free all cached but unused TABLEs and TABLE_SHAREs. */
506 10440 close_cached_tables(nullptr, nullptr, false, LONG_TIMEOUT);
507 }
508 10491 }
509
510 10545 void table_def_free(void) {
511
1/2
✓ Branch 0 taken 10545 times.
✗ Branch 1 not taken.
10545 DBUG_TRACE;
512
2/2
✓ Branch 0 taken 10494 times.
✓ Branch 1 taken 51 times.
10545 if (table_def_cache != nullptr) {
513 /* Free table definitions. */
514
1/2
✓ Branch 0 taken 10494 times.
✗ Branch 1 not taken.
10494 delete table_def_cache;
515 10494 table_def_cache = nullptr;
516
1/2
✓ Branch 0 taken 10494 times.
✗ Branch 1 not taken.
10494 table_cache_manager.destroy();
517
1/2
✓ Branch 0 taken 10494 times.
✗ Branch 1 not taken.
10494 mysql_cond_destroy(&COND_open);
518
1/2
✓ Branch 0 taken 10494 times.
✗ Branch 1 not taken.
10494 mysql_mutex_destroy(&LOCK_open);
519 }
520 10545 }
521
522 109258 uint cached_table_definitions(void) { return table_def_cache->size(); }
523
524 2410250 static TABLE_SHARE *process_found_table_share(THD *thd [[maybe_unused]],
525 TABLE_SHARE *share,
526 bool open_view) {
527
1/2
✓ Branch 0 taken 2410250 times.
✗ Branch 1 not taken.
2410250 DBUG_TRACE;
528 2410250 mysql_mutex_assert_owner(&LOCK_open);
529 #if defined(ENABLED_DEBUG_SYNC)
530
3/4
✓ Branch 0 taken 2410250 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1361439 times.
✓ Branch 3 taken 1048811 times.
2410250 if (!thd->is_attachable_ro_transaction_active())
531
3/4
✓ Branch 0 taken 1344517 times.
✓ Branch 1 taken 16922 times.
✓ Branch 2 taken 1344517 times.
✗ Branch 3 not taken.
1361439 DEBUG_SYNC(thd, "get_share_found_share");
532 #endif
533 /*
534 We found an existing table definition. Return it if we didn't get
535 an error when reading the table definition from file.
536 */
537
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2410250 times.
2410250 if (share->error) {
538 /*
539 Table definition contained an error.
540 Note that we report ER_NO_SUCH_TABLE regardless of which error occurred
541 when the other thread tried to open the table definition (e.g. OOM).
542 */
543 my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
544 return nullptr;
545 }
546
3/4
✓ Branch 0 taken 373509 times.
✓ Branch 1 taken 2036741 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 373509 times.
2410250 if (share->is_view && !open_view) {
547 my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
548 return nullptr;
549 }
550
551
1/2
✓ Branch 0 taken 2410250 times.
✗ Branch 1 not taken.
2410250 share->increment_ref_count();
552
553
6/8
✓ Branch 0 taken 2410250 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505868 times.
✓ Branch 3 taken 1904382 times.
✓ Branch 4 taken 505868 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 505868 times.
✓ Branch 7 taken 1904382 times.
2410250 if (share->ref_count() == 1 && share->prev) {
554 /*
555 Share was not used before and it was in the old_unused_share list
556 Unlink share from this list
557 */
558
5/8
✓ Branch 0 taken 505868 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505868 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
✓ Branch 5 taken 505851 times.
✓ Branch 6 taken 17 times.
✗ Branch 7 not taken.
505868 DBUG_PRINT("info", ("Unlinking from not used list"));
559 505868 *share->prev = share->next;
560 505868 share->next->prev = share->prev;
561 505868 share->next = nullptr;
562 505868 share->prev = nullptr;
563 }
564
565 /* Free cache if too big */
566
6/6
✓ Branch 0 taken 1374 times.
✓ Branch 1 taken 2409073 times.
✓ Branch 2 taken 197 times.
✓ Branch 3 taken 1177 times.
✓ Branch 4 taken 197 times.
✓ Branch 5 taken 2410250 times.
2410447 while (table_def_cache->size() > table_def_size && oldest_unused_share->next)
567
2/4
✓ Branch 0 taken 197 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197 times.
✗ Branch 3 not taken.
197 table_def_cache->erase(to_string(oldest_unused_share->table_cache_key));
568
569
6/10
✓ Branch 0 taken 2410250 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2410250 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
✓ Branch 5 taken 2410233 times.
✓ Branch 6 taken 17 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 17 times.
✗ Branch 9 not taken.
2410250 DBUG_PRINT("exit", ("share: %p ref_count: %u", share, share->ref_count()));
570 2410250 return share;
571 2410250 }
572
573 /**
574 Read any existing histogram statistics from the data dictionary and
575 store a copy of them in the TABLE_SHARE.
576
577 @param thd Thread handler
578 @param share The table share where to store the histograms
579 @param schema Schema definition
580 @param table_def Table definition
581
582 @retval true on error
583 @retval false on success
584 */
585 2075893 static bool read_histograms(THD *thd, TABLE_SHARE *share,
586 const dd::Schema *schema,
587 const dd::Abstract_table *table_def) {
588
1/2
✓ Branch 0 taken 2075893 times.
✗ Branch 1 not taken.
2075893 dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client());
589
1/2
✓ Branch 0 taken 2075893 times.
✗ Branch 1 not taken.
2075893 MDL_request_list mdl_requests;
590
6/10
✓ Branch 0 taken 2075893 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2075893 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2075893 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 22783066 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 22783065 times.
✓ Branch 9 taken 2075893 times.
24858960 for (const auto column : table_def->columns()) {
591
3/4
✓ Branch 0 taken 22783066 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3691901 times.
✓ Branch 3 taken 19091165 times.
22783066 if (column->is_se_hidden()) continue;
592
593 19091165 MDL_key mdl_key;
594
3/6
✓ Branch 0 taken 19091167 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19091166 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19091167 times.
✗ Branch 5 not taken.
19091167 dd::Column_statistics::create_mdl_key(schema->name(), table_def->name(),
595
1/2
✓ Branch 0 taken 19091167 times.
✗ Branch 1 not taken.
19091165 column->name(), &mdl_key);
596
597
1/2
✓ Branch 0 taken 19091166 times.
✗ Branch 1 not taken.
19091167 MDL_request *request = new (thd->mem_root) MDL_request;
598
1/2
✓ Branch 0 taken 19091167 times.
✗ Branch 1 not taken.
19091166 MDL_REQUEST_INIT_BY_KEY(request, &mdl_key, MDL_SHARED_READ, MDL_STATEMENT);
599
1/2
✓ Branch 0 taken 19091166 times.
✗ Branch 1 not taken.
19091167 mdl_requests.push_front(request);
600 }
601
602
2/4
✓ Branch 0 taken 2075893 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2075893 times.
2075893 if (thd->mdl_context.acquire_locks(&mdl_requests,
603 thd->variables.lock_wait_timeout))
604 return true; /* purecov: deadcode */
605
606
6/10
✓ Branch 0 taken 2075893 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2075893 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2075893 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 22783068 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 22783067 times.
✓ Branch 9 taken 2075893 times.
24858961 for (const auto column : table_def->columns()) {
607
3/4
✓ Branch 0 taken 22783067 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3691901 times.
✓ Branch 3 taken 19091166 times.
22783068 if (column->is_se_hidden()) continue;
608
609 19091166 const histograms::Histogram *histogram = nullptr;
610
6/12
✓ Branch 0 taken 19091166 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19091166 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 19091166 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 19091166 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 19091165 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 19091167 times.
57273498 if (histograms::find_histogram(thd, schema->name().c_str(),
611
1/2
✓ Branch 0 taken 19091166 times.
✗ Branch 1 not taken.
19091166 table_def->name().c_str(),
612
1/2
✓ Branch 0 taken 19091166 times.
✗ Branch 1 not taken.
19091166 column->name().c_str(), &histogram)) {
613 // Any error is reported by the dictionary subsystem.
614 return true; /* purecov: deadcode */
615 }
616
617
2/2
✓ Branch 0 taken 495 times.
✓ Branch 1 taken 19090672 times.
19091167 if (histogram != nullptr) {
618 /*
619 Make a clone of the histogram so it survives together with the
620 TABLE_SHARE in case the original histogram is thrown out of the
621 dictionary cache.
622 */
623 const histograms::Histogram *histogram_copy =
624
1/2
✓ Branch 0 taken 495 times.
✗ Branch 1 not taken.
495 histogram->clone(&share->mem_root);
625
2/4
✓ Branch 0 taken 495 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 495 times.
✗ Branch 3 not taken.
495 share->m_histograms->emplace(column->ordinal_position() - 1,
626 histogram_copy);
627 }
628 }
629
630 2075893 return false;
631 2075893 }
632
633 /** Update TABLE_SHARE with options from dd::Schema object */
634 2075892 static void update_schema_options(const dd::Schema *sch_obj,
635 TABLE_SHARE *share) {
636
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2075892 times.
2075892 assert(sch_obj != nullptr);
637
1/2
✓ Branch 0 taken 2075892 times.
✗ Branch 1 not taken.
2075892 if (sch_obj != nullptr) {
638
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 2075833 times.
2075892 if (sch_obj->read_only())
639 60 share->schema_read_only = TABLE_SHARE::Schema_read_only::RO_ON;
640 else
641 2075833 share->schema_read_only = TABLE_SHARE::Schema_read_only::RO_OFF;
642 }
643 2075893 }
644
645 /**
646 Get the TABLE_SHARE for a table.
647
648 Get a table definition from the table definition cache. If the share
649 does not exist, create a new one from the persistently stored table
650 definition, and temporarily release LOCK_open while retrieving it.
651 Re-lock LOCK_open when the table definition has been retrieved, and
652 broadcast this to other threads waiting for the share to become opened.
653
654 If the share exists, and is in the process of being opened, wait for
655 opening to complete before continuing.
656
657 @pre It is a precondition that the caller must own LOCK_open before
658 calling this function.
659
660 @note Callers of this function cannot rely on LOCK_open being
661 held for the duration of the call. It may be temporarily
662 released while the table definition is opened, and it may be
663 temporarily released while the thread is waiting for a different
664 thread to finish opening it.
665
666 @note After share->m_open_in_progress is set, there should be no wait
667 for resources like row- or metadata locks, table flushes, etc.
668 Otherwise, we may end up in deadlocks that will not be detected.
669
670 @param thd thread handle
671 @param db schema name
672 @param table_name table name
673 @param key table cache key
674 @param key_length length of key
675 @param open_view allow open of view
676 @param open_secondary get the share for a table in a secondary
677 storage engine
678
679 @return Pointer to the new TABLE_SHARE, or NULL if there was an error
680 */
681
682 4716558 TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name,
683 const char *key, size_t key_length, bool open_view,
684 bool open_secondary) {
685 TABLE_SHARE *share;
686 4716558 bool open_table_err = false;
687
1/2
✓ Branch 0 taken 4716558 times.
✗ Branch 1 not taken.
4716558 DBUG_TRACE;
688
689 /* Make sure we own LOCK_open */
690 4716558 mysql_mutex_assert_owner(&LOCK_open);
691
692 /*
693 To be able perform any operation on table we should own
694 some kind of metadata lock on it.
695 */
696
2/4
✓ Branch 0 taken 4716558 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4716558 times.
4716558 assert(thd->mdl_context.owns_equal_or_stronger_lock(MDL_key::TABLE, db,
697 table_name, MDL_SHARED));
698
699 /*
700 Read table definition from the cache. If the share is being opened,
701 wait for the appropriate condition. The share may be destroyed if
702 open fails, so after cond_wait, we must repeat searching the
703 hash table.
704 */
705 for (;;) {
706
2/4
✓ Branch 0 taken 5600949 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5600949 times.
✗ Branch 3 not taken.
5600949 auto it = table_def_cache->find(string(key, key_length));
707
2/2
✓ Branch 0 taken 3183174 times.
✓ Branch 1 taken 2417775 times.
5600949 if (it == table_def_cache->end()) {
708
3/4
✓ Branch 0 taken 3183174 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2306306 times.
✓ Branch 3 taken 876868 times.
3183174 if (thd->mdl_context.owns_equal_or_stronger_lock(
709 MDL_key::SCHEMA, db, "", MDL_INTENTION_EXCLUSIVE)) {
710 2306306 break;
711 }
712
1/2
✓ Branch 0 taken 876868 times.
✗ Branch 1 not taken.
876868 mysql_mutex_unlock(&LOCK_open);
713
714
3/4
✓ Branch 0 taken 876868 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 876866 times.
876868 if (dd::mdl_lock_schema(thd, db, MDL_TRANSACTION)) {
715 // Lock LOCK_open again to preserve function contract
716
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 mysql_mutex_lock(&LOCK_open);
717 2410252 return nullptr;
718 }
719
720
1/2
✓ Branch 0 taken 876866 times.
✗ Branch 1 not taken.
876866 mysql_mutex_lock(&LOCK_open);
721 // Need to re-try the find after getting the mutex again
722 876866 continue;
723 }
724 2417775 share = it->second.get();
725
2/2
✓ Branch 0 taken 2410250 times.
✓ Branch 1 taken 7525 times.
2417775 if (!share->m_open_in_progress)
726
1/2
✓ Branch 0 taken 2410250 times.
✗ Branch 1 not taken.
2410250 return process_found_table_share(thd, share, open_view);
727
728
3/4
✓ Branch 0 taken 7342 times.
✓ Branch 1 taken 183 times.
✓ Branch 2 taken 7342 times.
✗ Branch 3 not taken.
7525 DEBUG_SYNC(thd, "get_share_before_COND_open_wait");
729
1/2
✓ Branch 0 taken 7525 times.
✗ Branch 1 not taken.
7525 mysql_cond_wait(&COND_open, &LOCK_open);
730 884391 }
731
732 /*
733 If alloc fails, the share object will not be present in the TDC, so no
734 thread will be waiting for m_open_in_progress. Hence, a broadcast is
735 not necessary.
736 */
737
2/4
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2306306 times.
2306306 if (!(share = alloc_table_share(db, table_name, key, key_length,
738 open_secondary))) {
739 return nullptr;
740 }
741
742 /*
743 We assign a new table id under the protection of LOCK_open.
744 We do this instead of creating a new mutex
745 and using it for the sole purpose of serializing accesses to a
746 static variable, we assign the table id here. We assign it to the
747 share before inserting it into the table_def_cache to be really
748 sure that it cannot be read from the cache without having a table
749 id assigned.
750
751 CAVEAT. This means that the table cannot be used for
752 binlogging/replication purposes, unless get_table_share() has been
753 called directly or indirectly.
754 */
755
1/2
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
2306306 assign_new_table_id(share);
756
757
2/4
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2306306 times.
✗ Branch 3 not taken.
2306306 table_def_cache->emplace(to_string(share->table_cache_key),
758 4612612 unique_ptr<TABLE_SHARE, Table_share_deleter>(share));
759
760 /*
761 We must increase ref_count prior to releasing LOCK_open
762 to keep the share from being deleted in tdc_remove_table()
763 and TABLE_SHARE::wait_for_old_version. We must also set
764 m_open_in_progress to indicate allocated but incomplete share.
765 */
766
1/2
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
2306306 share->increment_ref_count(); // Mark in use
767 2306306 share->m_open_in_progress = true; // Mark being opened
768
769 /*
770 Temporarily release LOCK_open before opening the table definition,
771 which can be done without mutex protection.
772 */
773
1/2
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
2306306 mysql_mutex_unlock(&LOCK_open);
774
775 #if defined(ENABLED_DEBUG_SYNC)
776
3/4
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1325945 times.
✓ Branch 3 taken 980361 times.
2306306 if (!thd->is_attachable_ro_transaction_active())
777
3/4
✓ Branch 0 taken 1280557 times.
✓ Branch 1 taken 45388 times.
✓ Branch 2 taken 1280557 times.
✗ Branch 3 not taken.
1325945 DEBUG_SYNC(thd, "get_share_before_open");
778 #endif
779
780 {
781 // We must make sure the schema is released and unlocked in the right order.
782
1/2
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
2306306 dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client());
783 2306306 const dd::Schema *sch = nullptr;
784 2306306 const dd::Abstract_table *abstract_table = nullptr;
785 2306306 open_table_err = true; // Assume error to simplify code below.
786
4/10
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2306306 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2306306 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2306301 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
6918906 if (thd->dd_client()->acquire(share->db.str, &sch) ||
787
7/18
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2306306 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2306299 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2306299 times.
✓ Branch 8 taken 2306299 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2306300 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2306301 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
4612605 thd->dd_client()->acquire(share->db.str, share->table_name.str,
788 &abstract_table)) {
789
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 2306271 times.
2306301 } else if (sch == nullptr)
790
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 my_error(ER_BAD_DB_ERROR, MYF(0), share->db.str);
791
2/2
✓ Branch 0 taken 9182 times.
✓ Branch 1 taken 2297089 times.
2306271 else if (abstract_table == nullptr)
792
1/2
✓ Branch 0 taken 9182 times.
✗ Branch 1 not taken.
9182 my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
793
5/6
✓ Branch 0 taken 2297087 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2192498 times.
✓ Branch 3 taken 104589 times.
✓ Branch 4 taken 221180 times.
✓ Branch 5 taken 2075909 times.
4489589 else if (abstract_table->type() == dd::enum_table_type::USER_VIEW ||
794
3/4
✓ Branch 0 taken 2192500 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 116591 times.
✓ Branch 3 taken 2075909 times.
2192498 abstract_table->type() == dd::enum_table_type::SYSTEM_VIEW) {
795
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 221180 times.
221180 if (!open_view) // We found a view but were trying to open table only.
796 my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str,
797 share->table_name.str);
798 else {
799 /*
800 Clone the view reference object and hold it in
801 TABLE_SHARE member view_object.
802 */
803 221180 share->is_view = true;
804 const dd::View *tmp_view =
805
1/2
✓ Branch 0 taken 221180 times.
✗ Branch 1 not taken.
221180 dynamic_cast<const dd::View *>(abstract_table);
806
1/2
✓ Branch 0 taken 221180 times.
✗ Branch 1 not taken.
221180 share->view_object = tmp_view->clone();
807
808 221180 share->table_category =
809
1/2
✓ Branch 0 taken 221180 times.
✗ Branch 1 not taken.
221180 get_table_category(share->db, share->table_name);
810 221180 thd->status_var.opened_shares++;
811 221180 open_table_err = false;
812 }
813 } else {
814
2/4
✓ Branch 0 taken 2075909 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2075909 times.
2075909 assert(abstract_table->type() == dd::enum_table_type::BASE_TABLE);
815
1/2
✓ Branch 0 taken 2075908 times.
✗ Branch 1 not taken.
2075909 open_table_err = open_table_def(
816
1/2
✓ Branch 0 taken 2075909 times.
✗ Branch 1 not taken.
2075909 thd, share, *dynamic_cast<const dd::Table *>(abstract_table));
817
818 /*
819 Update the table share with meta data from the schema object to
820 have it readily available to avoid performance degradation.
821 */
822
3/4
✓ Branch 0 taken 2075893 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 2075894 times.
✗ Branch 3 not taken.
2075908 if (!open_table_err) update_schema_options(sch, share);
823
824 /*
825 Read any existing histogram statistics from the data dictionary and
826 store a copy of them in the TABLE_SHARE.
827
828 We need to do this outside the protection of LOCK_open, since the data
829 dictionary might have to open tables in order to read histogram data
830 (such recursion will not work).
831 */
832
5/8
✓ Branch 0 taken 2075893 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 2075892 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2075892 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2075908 times.
2075909 if (!open_table_err && read_histograms(thd, share, sch, abstract_table))
833 open_table_err = true; /* purecov: deadcode */
834 }
835 2306300 }
836
837 /*
838 Get back LOCK_open before continuing. Notify all waiters that the
839 opening is finished, even if there was a failure while opening.
840 */
841
1/2
✓ Branch 0 taken 2306301 times.
✗ Branch 1 not taken.
2306301 mysql_mutex_lock(&LOCK_open);
842 2306301 share->m_open_in_progress = false;
843
1/2
✓ Branch 0 taken 2306301 times.
✗ Branch 1 not taken.
2306301 mysql_cond_broadcast(&COND_open);
844
845 /*
846 Fake an open_table_def error in debug build, resulting in
847 ER_NO_SUCH_TABLE.
848 */
849
4/6
✓ Branch 0 taken 2306301 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2306299 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2306301 DBUG_EXECUTE_IF("set_open_table_err", {
850 open_table_err = true;
851 my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
852 });
853
854 /*
855 If there was an error while opening the definition, delete the
856 share from the TDC, and (implicitly) destroy the share. Waiters
857 will detect that the share is gone, and repeat the attempt at
858 opening the table definition. The ref counter must be stepped
859 down to allow the share to be destroyed.
860 */
861
2/2
✓ Branch 0 taken 9230 times.
✓ Branch 1 taken 2297071 times.
2306301 if (open_table_err) {
862 9230 share->error = true; // Allow waiters to detect the error
863
1/2
✓ Branch 0 taken 9230 times.
✗ Branch 1 not taken.
9230 share->decrement_ref_count();
864
2/4
✓ Branch 0 taken 9230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9230 times.
✗ Branch 3 not taken.
9230 table_def_cache->erase(to_string(share->table_cache_key));
865 #if defined(ENABLED_DEBUG_SYNC)
866
3/4
✓ Branch 0 taken 9230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9228 times.
✓ Branch 3 taken 2 times.
9230 if (!thd->is_attachable_ro_transaction_active())
867
3/4
✓ Branch 0 taken 6781 times.
✓ Branch 1 taken 2447 times.
✓ Branch 2 taken 6781 times.
✗ Branch 3 not taken.
9228 DEBUG_SYNC(thd, "get_share_after_destroy");
868 #endif
869 9230 return nullptr;
870 }
871
872 #ifdef HAVE_PSI_TABLE_INTERFACE
873 4594142 share->m_psi = PSI_TABLE_CALL(get_table_share)(
874
1/2
✓ Branch 0 taken 2297071 times.
✗ Branch 1 not taken.
2297071 (share->tmp_table != NO_TMP_TABLE), share);
875 #else
876 share->m_psi = NULL;
877 #endif
878
879
6/10
✓ Branch 0 taken 2297071 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2297071 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 52 times.
✓ Branch 5 taken 2297019 times.
✓ Branch 6 taken 52 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 52 times.
✗ Branch 9 not taken.
2297071 DBUG_PRINT("exit", ("share: %p ref_count: %u", share, share->ref_count()));
880
881 /* If debug, assert that the share is actually present in the cache */
882 #ifndef NDEBUG
883
3/6
✓ Branch 0 taken 2297071 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2297071 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2297071 times.
2297071 assert(table_def_cache->count(string(key, key_length)) != 0);
884 #endif
885 2297071 return share;
886 4716553 }
887
888 /**
889 Get a table share. If it didn't exist, try creating it from engine
890
891 For arguments and return values, see get_table_share()
892 */
893
894 4707336 static TABLE_SHARE *get_table_share_with_discover(
895 THD *thd, TABLE_LIST *table_list, const char *key, size_t key_length,
896 bool open_secondary, int *error)
897
898 {
899 TABLE_SHARE *share;
900 bool exists;
901
1/2
✓ Branch 0 taken 4707336 times.
✗ Branch 1 not taken.
4707336 DBUG_TRACE;
902
903
1/2
✓ Branch 0 taken 4707331 times.
✗ Branch 1 not taken.
4707336 share = get_table_share(thd, table_list->db, table_list->table_name, key,
904 key_length, true, open_secondary);
905 /*
906 If share is not NULL, we found an existing share.
907
908 If share is NULL, and there is no error, we're inside
909 pre-locking, which silences 'ER_NO_SUCH_TABLE' errors
910 with the intention to silently drop non-existing tables
911 from the pre-locking list. In this case we still need to try
912 auto-discover before returning a NULL share.
913
914 Or, we're inside SHOW CREATE VIEW, which
915 also installs a silencer for ER_NO_SUCH_TABLE error.
916
917 If share is NULL and the error is ER_NO_SUCH_TABLE, this is
918 the same as above, only that the error was not silenced by
919 pre-locking or SHOW CREATE VIEW.
920
921 In both these cases it won't harm to try to discover the
922 table.
923
924 Finally, if share is still NULL, it's a real error and we need
925 to abort.
926
927 @todo Rework alternative ways to deal with ER_NO_SUCH TABLE.
928 */
929
9/10
✓ Branch 0 taken 9231 times.
✓ Branch 1 taken 4698100 times.
✓ Branch 2 taken 9231 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2822 times.
✓ Branch 5 taken 6409 times.
✓ Branch 6 taken 47 times.
✓ Branch 7 taken 2775 times.
✓ Branch 8 taken 4698147 times.
✓ Branch 9 taken 9184 times.
4710153 if (share || (thd->is_error() &&
930 2822 thd->get_stmt_da()->mysql_errno() != ER_NO_SUCH_TABLE)) {
931 4698147 return share;
932 }
933
934 9184 *error = 0;
935
936 /* Table didn't exist. Check if some engine can provide it */
937
2/4
✓ Branch 0 taken 9184 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9184 times.
9184 if (ha_check_if_table_exists(thd, table_list->db, table_list->table_name,
938 &exists)) {
939 thd->clear_error();
940 thd->get_stmt_da()->reset_condition_info(thd);
941 /* Conventionally, the storage engine API does not report errors. */
942 my_error(ER_OUT_OF_RESOURCES, MYF(0));
943
1/2
✓ Branch 0 taken 9184 times.
✗ Branch 1 not taken.
9184 } else if (!exists) {
944 /*
945 No such table in any engine.
946 Hide "Table doesn't exist" errors if the table belongs to a view.
947 The check for thd->is_error() is necessary to not push an
948 unwanted error in case the error was already silenced.
949 @todo Rework the alternative ways to deal with ER_NO_SUCH TABLE.
950 */
951
3/4
✓ Branch 0 taken 9184 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2775 times.
✓ Branch 3 taken 6409 times.
9184 if (thd->is_error()) {
952
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2775 times.
2775 if (table_list->parent_l) {
953 thd->clear_error();
954 thd->get_stmt_da()->reset_condition_info(thd);
955 my_error(ER_WRONG_MRG_TABLE, MYF(0));
956
2/2
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 2724 times.
2775 } else if (table_list->belong_to_view) {
957 // Mention the top view in message, to not reveal underlying views.
958 51 TABLE_LIST *view = table_list->belong_to_view;
959
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 thd->clear_error();
960
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 thd->get_stmt_da()->reset_condition_info(thd);
961
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 my_error(ER_VIEW_INVALID, MYF(0), view->db, view->table_name);
962 }
963 }
964 } else {
965 thd->clear_error();
966 thd->get_stmt_da()->reset_condition_info(thd);
967 *error = 7; /* Run auto-discover. */
968 }
969 9184 return nullptr;
970 4707331 }
971
972 /**
973 Mark that we are not using table share anymore.
974
975 @param share Table share
976
977 If the share has no open tables and (we have done a refresh or
978 if we have already too many open table shares) then delete the
979 definition.
980 */
981
982 5077374 void release_table_share(TABLE_SHARE *share) {
983
1/2
✓ Branch 0 taken 5077374 times.
✗ Branch 1 not taken.
5077374 DBUG_TRACE;
984
6/10
✓ Branch 0 taken 5077374 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5077374 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 105 times.
✓ Branch 5 taken 5077269 times.
✓ Branch 6 taken 105 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 105 times.
✗ Branch 9 not taken.
5077374 DBUG_PRINT("enter", ("share: %p table: %s.%s ref_count: %u version: %lu",
985 share, share->db.str, share->table_name.str,
986 share->ref_count(), share->version()));
987
988 5077374 mysql_mutex_assert_owner(&LOCK_open);
989
990
2/4
✓ Branch 0 taken 5077374 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5077374 times.
5077374 assert(share->ref_count() != 0);
991
3/4
✓ Branch 0 taken 5077374 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2733910 times.
✓ Branch 3 taken 2343464 times.
5077374 if (share->decrement_ref_count() == 0) {
992
5/6
✓ Branch 0 taken 819946 times.
✓ Branch 1 taken 1913964 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 819946 times.
✓ Branch 4 taken 1913964 times.
✓ Branch 5 taken 819946 times.
2733910 if (share->has_old_version() || table_def_shutdown_in_progress)
993
2/4
✓ Branch 0 taken 1913964 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1913964 times.
✗ Branch 3 not taken.
1913964 table_def_cache->erase(to_string(share->table_cache_key));
994 else {
995 /* Link share last in used_table_share list */
996
5/8
✓ Branch 0 taken 819946 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 819946 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 819910 times.
✓ Branch 6 taken 36 times.
✗ Branch 7 not taken.
819946 DBUG_PRINT("info", ("moving share to unused list"));
997
998
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 819946 times.
819946 assert(share->next == nullptr);
999 819946 share->prev = end_of_unused_share.prev;
1000 819946 *end_of_unused_share.prev = share;
1001 819946 end_of_unused_share.prev = &share->next;
1002 819946 share->next = &end_of_unused_share;
1003
1004
2/2
✓ Branch 0 taken 637 times.
✓ Branch 1 taken 819309 times.
819946 if (table_def_cache->size() > table_def_size) {
1005 /* Delete the least used share to preserve LRU order. */
1006
2/4
✓ Branch 0 taken 637 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 637 times.
✗ Branch 3 not taken.
637 table_def_cache->erase(to_string(oldest_unused_share->table_cache_key));
1007 }
1008 }
1009 }
1010 5077374 }
1011
1012 /**
1013 Get an existing table definition from the table definition cache.
1014 */
1015
1016 632 TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name) {
1017 char key[MAX_DBKEY_LENGTH];
1018 size_t key_length;
1019 632 mysql_mutex_assert_owner(&LOCK_open);
1020
1021
1/2
✓ Branch 0 taken 632 times.
✗ Branch 1 not taken.
632 key_length = create_table_def_key(db, table_name, key);
1022
2/4
✓ Branch 0 taken 632 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 632 times.
✗ Branch 3 not taken.
632 return find_or_nullptr(*table_def_cache, string(key, key_length));
1023 }
1024
1025 /*
1026 Create a list for all open tables matching SQL expression
1027
1028 SYNOPSIS
1029 list_open_tables()
1030 thd Thread THD
1031 wild SQL like expression
1032
1033 NOTES
1034 One gets only a list of tables for which one has any kind of privilege.
1035 db and table names are allocated in result struct, so one doesn't need
1036 a lock on LOCK_open when traversing the return list.
1037
1038 RETURN VALUES
1039 NULL Error (Probably OOM)
1040 # Pointer to list of names of open tables.
1041 */
1042
1043 95 OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild) {
1044 OPEN_TABLE_LIST **start_list, *open_list, *start, *prev;
1045
1/2
✓ Branch 0 taken 95 times.
✗ Branch 1 not taken.
95 TABLE_LIST table_list;
1046
1/2
✓ Branch 0 taken 95 times.
✗ Branch 1 not taken.
95 DBUG_TRACE;
1047
1048 95 start_list = &open_list;
1049 95 open_list = nullptr;
1050
1051 /*
1052 This is done in two parts:
1053 1. First, we will make OPEN_TABLE_LIST under LOCK_open
1054 2. Second, we will check permission and unlink OPEN_TABLE_LIST
1055 entries if permission check fails
1056 */
1057
1058
1/2
✓ Branch 0 taken 95 times.
✗ Branch 1 not taken.
95 table_cache_manager.lock_all_and_tdc();
1059
1060
2/2
✓ Branch 0 taken 4646 times.
✓ Branch 1 taken 95 times.
4741 for (const auto &key_and_value : *table_def_cache) {
1061 4646 TABLE_SHARE *share = key_and_value.second.get();
1062
1063 /* Skip shares that are being opened */
1064
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 4644 times.
8070 if (share->m_open_in_progress) continue;
1065
7/8
✓ Branch 0 taken 2288 times.
✓ Branch 1 taken 2356 times.
✓ Branch 2 taken 2288 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2196 times.
✓ Branch 5 taken 92 times.
✓ Branch 6 taken 2196 times.
✓ Branch 7 taken 2448 times.
4644 if (db && my_strcasecmp(system_charset_info, db, share->db.str)) continue;
1066
6/6
✓ Branch 0 taken 1273 times.
✓ Branch 1 taken 1175 times.
✓ Branch 2 taken 1228 times.
✓ Branch 3 taken 45 times.
✓ Branch 4 taken 1228 times.
✓ Branch 5 taken 1220 times.
3721 if (wild && wild_compare(share->table_name.str, share->table_name.length,
1067
1/2
✓ Branch 0 taken 1273 times.
✗ Branch 1 not taken.
1273 wild, strlen(wild), false))
1068 1228 continue;
1069
1070
1/2
✓ Branch 0 taken 1220 times.
✗ Branch 1 not taken.
1220 if (!(*start_list = (OPEN_TABLE_LIST *)(*THR_MALLOC)
1071
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1220 times.
1220 ->Alloc(sizeof(**start_list) +
1072
1/2
✓ Branch 0 taken 1220 times.
✗ Branch 1 not taken.
1220 share->table_cache_key.length))) {
1073 open_list = nullptr; // Out of memory
1074 break;
1075 }
1076 2440 my_stpcpy((*start_list)->table =
1077 1220 my_stpcpy(((*start_list)->db = (char *)((*start_list) + 1)),
1078 1220 share->db.str) +
1079 1,
1080 share->table_name.str);
1081 1220 (*start_list)->in_use = 0;
1082
1/2
✓ Branch 0 taken 1220 times.
✗ Branch 1 not taken.
1220 Table_cache_iterator it(share);
1083
3/4
✓ Branch 0 taken 1258 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 1220 times.
1258 while (it++) ++(*start_list)->in_use;
1084 1220 (*start_list)->locked = 0; /* Obsolete. */
1085 1220 start_list = &(*start_list)->next;
1086 1220 *start_list = nullptr;
1087 }
1088
1/2
✓ Branch 0 taken 95 times.
✗ Branch 1 not taken.
95 table_cache_manager.unlock_all_and_tdc();
1089
1090 95 start = open_list;
1091 95 prev = start;
1092
1093
2/2
✓ Branch 0 taken 1220 times.
✓ Branch 1 taken 95 times.
1315 while (start) {
1094 /* Check if user has SELECT privilege for any column in the table */
1095 1220 table_list.db = start->db;
1096 1220 table_list.table_name = start->table;
1097 1220 table_list.grant.privilege = 0;
1098
1099
2/4
✓ Branch 0 taken 1220 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1220 times.
1220 if (check_table_access(thd, SELECT_ACL, &table_list, true, 1, true)) {
1100 /* Unlink OPEN_TABLE_LIST */
1101 if (start == open_list) {
1102 open_list = start->next;
1103 prev = open_list;
1104 } else
1105 prev->next = start->next;
1106 } else
1107 1220 prev = start;
1108 1220 start = start->next;
1109 }
1110
1111 95 return open_list;
1112 95 }
1113
1114 /*****************************************************************************
1115 * Functions to free open table cache
1116 ****************************************************************************/
1117
1118 4482141 void intern_close_table(TABLE *table) { // Free all structures
1119
1/2
✓ Branch 0 taken 4482141 times.
✗ Branch 1 not taken.
4482141 DBUG_TRACE;
1120
7/12
✓ Branch 0 taken 4482141 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4482141 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✓ Branch 5 taken 4482061 times.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 80 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 80 times.
✗ Branch 11 not taken.
4482141 DBUG_PRINT("tcache",
1121 ("table: '%s'.'%s' %p", table->s ? table->s->db.str : "?",
1122 table->s ? table->s->table_name.str : "?", table));
1123
1124
1/2
✓ Branch 0 taken 4482141 times.
✗ Branch 1 not taken.
4482141 free_io_cache(table);
1125 4482141 destroy(table->triggers);
1126
1/2
✓ Branch 0 taken 4482141 times.
✗ Branch 1 not taken.
4482141 if (table->file) // Not true if placeholder
1127
1/2
✓ Branch 0 taken 4482141 times.
✗ Branch 1 not taken.
4482141 (void)closefrm(table, true); // close file
1128 4482141 destroy(table);
1129
1/2
✓ Branch 0 taken 4482141 times.
✗ Branch 1 not taken.
4482141 my_free(table);
1130 4482141 }
1131
1132 /* Free resources allocated by filesort() and read_record() */
1133
1134 138666509 void free_io_cache(TABLE *table) {
1135
1/2
✓ Branch 0 taken 138667208 times.
✗ Branch 1 not taken.
138666509 DBUG_TRACE;
1136
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 138667208 times.
138667208 if (table->unique_result.io_cache) {
1137 close_cached_file(table->unique_result.io_cache);
1138 my_free(table->unique_result.io_cache);
1139 table->unique_result.io_cache = nullptr;
1140 }
1141 138667208 }
1142
1143 /*
1144 Close all tables which aren't in use by any thread
1145
1146 @param thd Thread context
1147 @param tables List of tables to remove from the cache
1148 @param wait_for_refresh Wait for a impending flush
1149 @param timeout Timeout for waiting for flush to be completed.
1150
1151 @note THD can be NULL, but then wait_for_refresh must be false
1152 and tables must be NULL.
1153
1154 @note When called as part of FLUSH TABLES WITH READ LOCK this function
1155 ignores metadata locks held by other threads. In order to avoid
1156 situation when FLUSH TABLES WITH READ LOCK sneaks in at the moment
1157 when some write-locked table is being reopened (by FLUSH TABLES or
1158 ALTER TABLE) we have to rely on additional global shared metadata
1159 lock taken by thread trying to obtain global read lock.
1160 */
1161
1162 47102 bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool wait_for_refresh,
1163 ulong timeout) {
1164 47102 bool result = false;
1165 47102 bool found = true;
1166 struct timespec abstime;
1167
1/2
✓ Branch 0 taken 47102 times.
✗ Branch 1 not taken.
47102 DBUG_TRACE;
1168
4/6
✓ Branch 0 taken 22389 times.
✓ Branch 1 taken 24713 times.
✓ Branch 2 taken 22389 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22389 times.
✗ Branch 5 not taken.
47102 assert(thd || (!wait_for_refresh && !tables));
1169
1170
1/2
✓ Branch 0 taken 47102 times.
✗ Branch 1 not taken.
47102 table_cache_manager.lock_all_and_tdc();
1171
2/2
✓ Branch 0 taken 46800 times.
✓ Branch 1 taken 302 times.
47102 if (!tables) {
1172 /*
1173 Force close of all open tables.
1174
1175 Note that code in TABLE_SHARE::wait_for_old_version() assumes that
1176 incrementing of refresh_version and removal of unused tables and
1177 shares from TDC happens atomically under protection of LOCK_open,
1178 or putting it another way that TDC does not contain old shares
1179 which don't have any tables used.
1180 */
1181 46800 refresh_version++;
1182
3/8
✓ Branch 0 taken 46800 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46800 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 46800 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
46800 DBUG_PRINT("tcache",
1183 ("incremented global refresh_version to: %lu", refresh_version));
1184
1185 /*
1186 Get rid of all unused TABLE and TABLE_SHARE instances. By doing
1187 this we automatically close all tables which were marked as "old".
1188 */
1189
1/2
✓ Branch 0 taken 46800 times.
✗ Branch 1 not taken.
46800 table_cache_manager.free_all_unused_tables();
1190 /* Free table shares which were not freed implicitly by loop above. */
1191
2/2
✓ Branch 0 taken 200602 times.
✓ Branch 1 taken 46800 times.
247402 while (oldest_unused_share->next)
1192
2/4
✓ Branch 0 taken 200602 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 200602 times.
✗ Branch 3 not taken.
200602 table_def_cache->erase(to_string(oldest_unused_share->table_cache_key));
1193 } else {
1194 302 bool share_found = false;
1195
2/2
✓ Branch 0 taken 313 times.
✓ Branch 1 taken 302 times.
615 for (TABLE_LIST *table = tables; table; table = table->next_local) {
1196
1/2
✓ Branch 0 taken 313 times.
✗ Branch 1 not taken.
313 TABLE_SHARE *share = get_cached_table_share(table->db, table->table_name);
1197
1198
2/2
✓ Branch 0 taken 283 times.
✓ Branch 1 taken 30 times.
313 if (share) {
1199 /*
1200 tdc_remove_table() also sets TABLE_SHARE::version to 0. Note that
1201 it will work correctly even if m_open_in_progress flag is true.
1202 */
1203
1/2
✓ Branch 0 taken 283 times.
✗ Branch 1 not taken.
283 tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, table->db,
1204 table->table_name, true);
1205 283 share_found = true;
1206 }
1207 }
1208
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 275 times.
302 if (!share_found) wait_for_refresh = false; // Nothing to wait for
1209 }
1210
1211
1/2
✓ Branch 0 taken 47102 times.
✗ Branch 1 not taken.
47102 table_cache_manager.unlock_all_and_tdc();
1212
1213
2/2
✓ Branch 0 taken 22422 times.
✓ Branch 1 taken 24680 times.
47102 if (!wait_for_refresh) return result;
1214
1215
1/2
✓ Branch 0 taken 24680 times.
✗ Branch 1 not taken.
24680 set_timespec(&abstime, timeout);
1216
1217
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 24653 times.
24680 if (thd->locked_tables_mode) {
1218 /*
1219 If we are under LOCK TABLES, we need to reopen the tables without
1220 opening a door for any concurrent threads to sneak in and get
1221 lock on our tables. To achieve this we use exclusive metadata
1222 locks.
1223 */
1224 TABLE_LIST *tables_to_reopen =
1225
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 22 times.
27 (tables ? tables : thd->locked_tables_list.locked_tables());
1226
1227 /* Close open HANLER instances to avoid self-deadlock. */
1228
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 mysql_ha_flush_tables(thd, tables_to_reopen);
1229
1230
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 27 times.
56 for (TABLE_LIST *table_list = tables_to_reopen; table_list;
1231 29 table_list = table_list->next_global) {
1232 /* A check that the table was locked for write is done by the caller. */
1233
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 TABLE *table = find_table_for_mdl_upgrade(thd, table_list->db,
1234 table_list->table_name, true);
1235
1236 /* May return NULL if this table has already been closed via an alias. */
1237
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
29 if (!table) continue;
1238
1239
2/4
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 29 times.
29 if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN)) {
1240 result = true;
1241 goto err_with_reopen;
1242 }
1243
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 close_all_tables_for_name(thd, table->s, false, nullptr);
1244 }
1245 }
1246
1247 /* Wait until all threads have closed all the tables we are flushing. */
1248
3/8
✓ Branch 0 taken 24680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24680 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 24680 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
24680 DBUG_PRINT("info", ("Waiting for other threads to close their open tables"));
1249
1250
6/6
✓ Branch 0 taken 24812 times.
✓ Branch 1 taken 24677 times.
✓ Branch 2 taken 24809 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 24809 times.
✓ Branch 5 taken 24680 times.
49489 while (found && !thd->killed) {
1251 24809 TABLE_SHARE *share = nullptr;
1252 24809 found = false;
1253 /*
1254 To a self-deadlock or deadlocks with other FLUSH threads
1255 waiting on our open HANDLERs, we have to flush them.
1256 */
1257
1/2
✓ Branch 0 taken 24809 times.
✗ Branch 1 not taken.
24809 mysql_ha_flush(thd);
1258
3/4
✓ Branch 0 taken 24614 times.
✓ Branch 1 taken 195 times.
✓ Branch 2 taken 24614 times.
✗ Branch 3 not taken.
24809 DEBUG_SYNC(thd, "after_flush_unlock");
1259
1260
1/2
✓ Branch 0 taken 24809 times.
✗ Branch 1 not taken.
24809 mysql_mutex_lock(&LOCK_open);
1261
1262
2/2
✓ Branch 0 taken 24537 times.
✓ Branch 1 taken 272 times.
24809 if (!tables) {
1263
2/2
✓ Branch 0 taken 284 times.
✓ Branch 1 taken 24408 times.
24692 for (const auto &key_and_value : *table_def_cache) {
1264 284 share = key_and_value.second.get();
1265
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 155 times.
284 if (share->has_old_version()) {
1266 129 found = true;
1267 129 break;
1268 }
1269 }
1270 } else {
1271
2/2
✓ Branch 0 taken 279 times.
✓ Branch 1 taken 269 times.
548 for (TABLE_LIST *table = tables; table; table = table->next_local) {
1272
1/2
✓ Branch 0 taken 279 times.
✗ Branch 1 not taken.
279 share = get_cached_table_share(table->db, table->table_name);
1273
6/6
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 275 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 276 times.
279 if (share && share->has_old_version()) {
1274 3 found = true;
1275 3 break;
1276 }
1277 }
1278 }
1279
1280
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 24677 times.
24809 if (found) {
1281 /*
1282 The method below temporarily unlocks LOCK_open and frees
1283 share's memory. Note that it works correctly even for
1284 shares with m_open_in_progress flag set.
1285 */
1286
2/4
✓ Branch 0 taken 132 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 132 times.
132 if (share->wait_for_old_version(
1287 thd, &abstime, MDL_wait_for_subgraph::DEADLOCK_WEIGHT_DDL)) {
1288 mysql_mutex_unlock(&LOCK_open);
1289 result = true;
1290 goto err_with_reopen;
1291 }
1292 }
1293
1294
1/2
✓ Branch 0 taken 24809 times.
✗ Branch 1 not taken.
24809 mysql_mutex_unlock(&LOCK_open);
1295 }
1296
1297 24680 err_with_reopen:
1298
2/2
✓ Branch 0 taken 27 times.
✓ Branch 1 taken 24653 times.
24680 if (thd->locked_tables_mode) {
1299 /*
1300 No other thread has the locked tables open; reopen them and get the
1301 old locks. This should succeed unless any dictionary operations fail
1302 (e.g. when opening a dictionary table on cache miss).
1303 */
1304
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 result |= thd->locked_tables_list.reopen_tables(thd);
1305 /*
1306 Since downgrade_lock() won't do anything with shared
1307 metadata lock it is much simpler to go through all open tables rather
1308 than picking only those tables that were flushed.
1309 */
1310
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 27 times.
69 for (TABLE *tab = thd->open_tables; tab; tab = tab->next)
1311
1/2
✓ Branch 0 taken 42 times.
✗ Branch 1 not taken.
42 tab->mdl_ticket->downgrade_lock(MDL_SHARED_NO_READ_WRITE);
1312 }
1313
3/4
✓ Branch 0 taken 24680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 24677 times.
24680 return result || thd->killed;
1314 47102 }
1315
1316 /**
1317 Mark all temporary tables which were used by the current statement or
1318 substatement as free for reuse, but only if the query_id can be cleared.
1319
1320 @param thd thread context
1321
1322 @remark For temp tables associated with a open SQL HANDLER the query_id
1323 is not reset until the HANDLER is closed.
1324 */
1325
1326 64546570 static void mark_temp_tables_as_free_for_reuse(THD *thd) {
1327
2/2
✓ Branch 0 taken 3461902 times.
✓ Branch 1 taken 64546571 times.
68008473 for (TABLE *table = thd->temporary_tables; table; table = table->next) {
1328
4/4
✓ Branch 0 taken 254384 times.
✓ Branch 1 taken 3207518 times.
✓ Branch 2 taken 254355 times.
✓ Branch 3 taken 29 times.
3461902 if ((table->query_id == thd->query_id) && !table->open_by_handler) {
1329 254355 mark_tmp_table_for_reuse(table);
1330 254355 table->cleanup_value_generator_items();
1331 254355 table->cleanup_partial_update();
1332 }
1333 }
1334 64546571 }
1335
1336 /**
1337 Reset a single temporary table.
1338 Effectively this "closes" one temporary table,
1339 in a session.
1340
1341 @param table Temporary table.
1342 */
1343
1344 254384 void mark_tmp_table_for_reuse(TABLE *table) {
1345
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 254384 times.
254384 assert(table->s->tmp_table);
1346
1347 254384 table->query_id = 0;
1348 254384 table->file->ha_reset();
1349
1350 /* Detach temporary MERGE children from temporary parent. */
1351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 254384 times.
254384 assert(table->file);
1352 254384 table->file->ha_extra(HA_EXTRA_DETACH_CHILDREN);
1353
1354 /*
1355 Reset temporary table lock type to it's default value (TL_WRITE).
1356
1357 Statements such as INSERT INTO .. SELECT FROM tmp, CREATE TABLE
1358 .. SELECT FROM tmp and UPDATE may under some circumstances modify
1359 the lock type of the tables participating in the statement. This
1360 isn't a problem for non-temporary tables since their lock type is
1361 reset at every open, but the same does not occur for temporary
1362 tables for historical reasons.
1363
1364 Furthermore, the lock type of temporary tables is not really that
1365 important because they can only be used by one query at a time and
1366 not even twice in a query -- a temporary table is represented by
1367 only one TABLE object. Nonetheless, it's safer from a maintenance
1368 point of view to reset the lock type of this singleton TABLE object
1369 as to not cause problems when the table is reused.
1370
1371 Even under LOCK TABLES mode its okay to reset the lock type as
1372 LOCK TABLES is allowed (but ignored) for a temporary table.
1373 */
1374 254384 table->reginfo.lock_type = TL_WRITE;
1375 254384 }
1376
1377 /*
1378 Mark all tables in the list which were used by current substatement
1379 as free for reuse.
1380
1381 SYNOPSIS
1382 mark_used_tables_as_free_for_reuse()
1383 thd - thread context
1384 table - head of the list of tables
1385
1386 DESCRIPTION
1387 Marks all tables in the list which were used by current substatement
1388 (they are marked by its query_id) as free for reuse.
1389
1390 NOTE
1391 The reason we reset query_id is that it's not enough to just test
1392 if table->query_id != thd->query_id to know if a table is in use.
1393
1394 For example
1395 SELECT f1_that_uses_t1() FROM t1;
1396 In f1_that_uses_t1() we will see one instance of t1 where query_id is
1397 set to query_id of original query.
1398 */
1399
1400 3035539 static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table) {
1401
2/2
✓ Branch 0 taken 4104866 times.
✓ Branch 1 taken 3035539 times.
7140405 for (; table; table = table->next) {
1402
3/4
✓ Branch 0 taken 900082 times.
✓ Branch 1 taken 3204784 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 900082 times.
4104866 assert(table->pos_in_locked_tables == nullptr ||
1403 table->pos_in_locked_tables->table == table);
1404
2/2
✓ Branch 0 taken 2369627 times.
✓ Branch 1 taken 1735239 times.
4104866 if (table->query_id == thd->query_id) {
1405 2369627 table->query_id = 0;
1406 2369627 table->file->ha_reset();
1407 }
1408 }
1409 3035539 }
1410
1411 /**
1412 Auxiliary function to close all tables in the open_tables list.
1413
1414 @param thd Thread context.
1415
1416 @remark It should not ordinarily be called directly.
1417 */
1418
1419 40654310 static void close_open_tables(THD *thd) {
1420 40654310 mysql_mutex_assert_not_owner(&LOCK_open);
1421
1422
2/2
✓ Branch 0 taken 1374 times.
✓ Branch 1 taken 40654036 times.
40655514 DBUG_PRINT("info", ("thd->open_tables: %p", thd->open_tables));
1423
1424
2/2
✓ Branch 0 taken 117268405 times.
✓ Branch 1 taken 40655147 times.
157923552 while (thd->open_tables) close_thread_table(thd, &thd->open_tables);
1425 40655147 }
1426
1427 /**
1428 Close all open instances of the table but keep the MDL lock.
1429
1430 Works both under LOCK TABLES and in the normal mode.
1431 Removes all closed instances of the table from the table cache.
1432
1433 @param thd Thread context.
1434 @param key TC/TDC key identifying the table.
1435 @param key_length Length of TC/TDC key identifying the table.
1436 @param db Database name.
1437 @param table_name Table name.
1438 @param remove_from_locked_tables
1439 True if the table is being dropped.
1440 In that case the documented behaviour is to
1441 implicitly remove the table from LOCK TABLES list.
1442 @param skip_table TABLE instance that should be kept open.
1443
1444 @pre Must be called with an X MDL lock on the table.
1445 */
1446 594488 static void close_all_tables_for_name(THD *thd, const char *key,
1447 size_t key_length, const char *db,
1448 const char *table_name,
1449 bool remove_from_locked_tables,
1450 TABLE *skip_table) {
1451 594488 mysql_mutex_assert_not_owner(&LOCK_open);
1452
2/2
✓ Branch 0 taken 100595 times.
✓ Branch 1 taken 594488 times.
695083 for (TABLE **prev = &thd->open_tables; *prev;) {
1453 100595 TABLE *table = *prev;
1454
1455
2/2
✓ Branch 0 taken 100407 times.
✓ Branch 1 taken 188 times.
100595 if (table->s->table_cache_key.length == key_length &&
1456
4/4
✓ Branch 0 taken 100158 times.
✓ Branch 1 taken 249 times.
✓ Branch 2 taken 93947 times.
✓ Branch 3 taken 6211 times.
100407 !memcmp(table->s->table_cache_key.str, key, key_length) &&
1457 table != skip_table) {
1458 93947 thd->locked_tables_list.unlink_from_list(thd, table->pos_in_locked_tables,
1459 remove_from_locked_tables);
1460 /*
1461 Does nothing if the table is not locked.
1462 This allows one to use this function after a table
1463 has been unlocked, e.g. in partition management.
1464 */
1465 93947 mysql_lock_remove(thd, thd->lock, table);
1466
1467 /* Inform handler that table will be dropped after close */
1468
3/4
✓ Branch 0 taken 93947 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 93940 times.
✓ Branch 3 taken 7 times.
93947 if (table->db_stat && /* Not true for partitioned tables. */
1469 skip_table == nullptr)
1470 93940 table->file->ha_extra(HA_EXTRA_PREPARE_FOR_DROP);
1471 93947 close_thread_table(thd, prev);
1472 } else {
1473 /* Step to next entry in open_tables list. */
1474 6648 prev = &table->next;
1475 }
1476 }
1477
2/2
✓ Branch 0 taken 588277 times.
✓ Branch 1 taken 6211 times.
594488 if (skip_table == nullptr) {
1478 /* Remove the table share from the cache. */
1479 588277 tdc_remove_table(thd, TDC_RT_REMOVE_ALL, db, table_name, false);
1480 }
1481 594488 }
1482
1483 100022 void close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
1484 bool remove_from_locked_tables,
1485 TABLE *skip_table) {
1486 char key[MAX_DBKEY_LENGTH];
1487 100022 size_t key_length = share->table_cache_key.length;
1488
1489 100022 memcpy(key, share->table_cache_key.str, key_length);
1490
1491 100022 close_all_tables_for_name(thd, key, key_length,
1492 key, // db
1493
1/2
✓ Branch 0 taken 100022 times.
✗ Branch 1 not taken.
100022 key + share->db.length + 1, // table_name
1494 remove_from_locked_tables, skip_table);
1495 100022 }
1496
1497 494466 void close_all_tables_for_name(THD *thd, const char *db, const char *table_name,
1498 bool remove_from_locked_tables) {
1499 char key[MAX_DBKEY_LENGTH];
1500
1/2
✓ Branch 0 taken 494466 times.
✗ Branch 1 not taken.
494466 size_t key_length = create_table_def_key(db, table_name, key);
1501
1502
1/2
✓ Branch 0 taken 494466 times.
✗ Branch 1 not taken.
494466 close_all_tables_for_name(thd, key, key_length, db, table_name,
1503 remove_from_locked_tables, nullptr);
1504 494466 }
1505
1506 // Check if we are under LOCK TABLE mode, and not prelocking.
1507 120707547 static inline bool in_LTM(THD *thd) {
1508
2/2
✓ Branch 0 taken 120561560 times.
✓ Branch 1 taken 145987 times.
241269107 return (thd->locked_tables_mode == LTM_LOCK_TABLES ||
1509
2/2
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 120560920 times.
241269107 thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES);
1510 }
1511
1512 /**
1513 Check if the given TABLE_LIST belongs to a DD table.
1514
1515 The function checks whether the table is a DD table being used in the
1516 context of a DD transaction, or whether it is referred by a system view.
1517 Then, it implies that if either of these two conditions hold, then this
1518 is a DD table. If in case this is a DD table being used in some other
1519 situation, then this function does not return 'true'. We do not know if
1520 there is such a situation right now.
1521
1522 This function ignores TABLE_LIST's that is created by optimizer
1523 when processing a system view.
1524
1525 @param tl TABLE_LIST point to the table.
1526
1527 @retval true If table belongs to a DD table.
1528 @retval false If table does not.
1529 */
1530 118523765 static bool belongs_to_dd_table(const TABLE_LIST *tl) {
1531
2/2
✓ Branch 0 taken 23420046 times.
✓ Branch 1 taken 95103719 times.
141944718 return (tl->is_dd_ctx_table ||
1532
4/4
✓ Branch 0 taken 23420488 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 23420608 times.
✓ Branch 3 taken 107 times.
23420046 (!tl->is_internal() && !tl->uses_materialization() &&
1533
4/4
✓ Branch 0 taken 2772253 times.
✓ Branch 1 taken 20648355 times.
✓ Branch 2 taken 2499267 times.
✓ Branch 3 taken 272986 times.
141945280 tl->referencing_view && tl->referencing_view->is_system_view));
1534 }
1535
1536 /**
1537 Close all tables used by the current substatement, or all tables
1538 used by this thread if we are on the outer-most level.
1539
1540 @param thd Thread handler
1541
1542 @details
1543 Unlocks all open persistent and temporary base tables.
1544 Put all persistent base tables used by thread in free list.
1545
1546 It will only close/mark as free for reuse tables opened by this
1547 substatement, it will also check if we are closing tables after
1548 execution of complete query (i.e. we are on outer-most level) and will
1549 leave prelocked mode if needed.
1550 */
1551
1552 64545475 void close_thread_tables(THD *thd) {
1553
1/2
✓ Branch 0 taken 64547537 times.
✗ Branch 1 not taken.
64545475 DBUG_TRACE;
1554
1555 #ifdef EXTRA_DEBUG
1556 DBUG_PRINT("tcache", ("open tables:"));
1557 for (TABLE *table = thd->open_tables; table; table = table->next)
1558 DBUG_PRINT("tcache", ("table: '%s'.'%s' %p", table->s->db.str,
1559 table->s->table_name.str, table));
1560 #endif
1561
1562 #if defined(ENABLED_DEBUG_SYNC)
1563 /* debug_sync may not be initialized for some slave threads */
1564
4/6
✓ Branch 0 taken 60339930 times.
✓ Branch 1 taken 4207607 times.
✓ Branch 2 taken 60339643 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 60340215 times.
✗ Branch 5 not taken.
64547537 if (thd->debug_sync_control) DEBUG_SYNC(thd, "before_close_thread_tables");
1565 #endif
1566
1567 // TODO: dd::Transaction_impl::end() does merge DD transaction into
1568 // thd->transaction.stmt. Later the can be second DD transaction
1569 // which would call close_thread_tables(). In this case, the
1570 // condition thd->transaction.stmt.is_empty() does not hold good.
1571 // So we comment this assert for now.
1572 //
1573 // We should consider retaining this assert if we plan to commit
1574 // DD RW transaction just before next close_thread_tables().
1575 // We are not sure if this is doable and needs to be explored.
1576 // Alik and myself plan to comment this assert for now temporarily
1577 // and address this TODO asap.
1578 //
1579 // assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT) ||
1580 // thd->in_sub_stmt ||
1581 // (thd->state_flags & Open_tables_state::BACKUPS_AVAIL));
1582
1583 /* Detach MERGE children after every statement. Even under LOCK TABLES. */
1584
2/2
✓ Branch 0 taken 119069425 times.
✓ Branch 1 taken 64547533 times.
183616958 for (TABLE *table = thd->open_tables; table; table = table->next) {
1585 /* Table might be in use by some outer statement. */
1586
5/8
✓ Branch 0 taken 119069461 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 119069533 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6084 times.
✓ Branch 5 taken 119063449 times.
✓ Branch 6 taken 6084 times.
✗ Branch 7 not taken.
119069425 DBUG_PRINT("tcache", ("table: '%s' query_id: %lu",
1587 table->s->table_name.str, (ulong)table->query_id));
1588
2/2
✓ Branch 0 taken 3205597 times.
✓ Branch 1 taken 115863936 times.
119069533 if (thd->locked_tables_mode <= LTM_LOCK_TABLES ||
1589
2/2
✓ Branch 0 taken 2365398 times.
✓ Branch 1 taken 840199 times.
3205597 table->query_id == thd->query_id) {
1590
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 118229334 times.
118229334 assert(table->file);
1591
3/4
✓ Branch 0 taken 118049762 times.
✓ Branch 1 taken 179572 times.
✓ Branch 2 taken 118049239 times.
✗ Branch 3 not taken.
118229334 if (table->db_stat) table->file->ha_extra(HA_EXTRA_DETACH_CHILDREN);
1592
1/2
✓ Branch 0 taken 118228823 times.
✗ Branch 1 not taken.
118228811 table->cleanup_value_generator_items();
1593
1/2
✓ Branch 0 taken 118229012 times.
✗ Branch 1 not taken.
118228823 table->cleanup_partial_update();
1594 }
1595 }
1596
1597 /*
1598 Mark all temporary tables used by this statement as free for reuse.
1599 */
1600
1/2
✓ Branch 0 taken 64546790 times.
✗ Branch 1 not taken.
64547533 mark_temp_tables_as_free_for_reuse(thd);
1601
1602
2/2
✓ Branch 0 taken 3035539 times.
✓ Branch 1 taken 61511251 times.
64546790 if (thd->locked_tables_mode) {
1603 /*
1604 If we have
1605 1) Implicitly opened some DD tables that belong to IS system
1606 view executed in LOCK TABLE mode, then we should close them now.
1607 2) Close P_S tables opened implicitly under LOCK TABLE mode.
1608 */
1609
2/2
✓ Branch 0 taken 33455 times.
✓ Branch 1 taken 3002084 times.
3035539 if (in_LTM(thd)) {
1610
2/2
✓ Branch 0 taken 942260 times.
✓ Branch 1 taken 33455 times.
975715 for (TABLE **prev = &thd->open_tables; *prev;) {
1611 942260 TABLE *table = *prev;
1612
1613 /* Ignore tables locked explicitly by LOCK TABLE. */
1614
2/2
✓ Branch 0 taken 42178 times.
✓ Branch 1 taken 900082 times.
942260 if (!table->pos_in_locked_tables) {
1615 /*
1616 We close tables only when all of following conditions satisfy,
1617 - The table is not locked explicitly by user using LOCK TABLE
1618 command.
1619 - We are not executing a IS queries as part of SF/Trigger.
1620 - The table belongs to a new DD table.
1621 OR
1622 - Close P_S tables unless the query is inside of a SP/trigger.
1623 */
1624 42178 TABLE_LIST *tbl_list = table->pos_in_table_list;
1625
5/8
✓ Branch 0 taken 42178 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 698 times.
✓ Branch 3 taken 41480 times.
✓ Branch 4 taken 698 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 42178 times.
✗ Branch 7 not taken.
42876 if (!thd->in_sub_stmt && (belongs_to_dd_table(tbl_list) ||
1626 698 belongs_to_p_s(table->pos_in_table_list))) {
1627
1/2
✓ Branch 0 taken 42178 times.
✗ Branch 1 not taken.
42178 if (!table->s->tmp_table) {
1628
1/2
✓ Branch 0 taken 42178 times.
✗ Branch 1 not taken.
42178 table->file->ha_index_or_rnd_end();
1629
1/2
✓ Branch 0 taken 42178 times.
✗ Branch 1 not taken.
42178 table->set_keyread(false);
1630 42178 table->open_by_handler = false;
1631 /*
1632 In case we have opened the DD table but the statement
1633 fails before calling ha_external_lock() requesting
1634 read lock in open_tables(), then we need to check
1635 if we have really requested lock and then unlock.
1636 */
1637
2/2
✓ Branch 0 taken 41985 times.
✓ Branch 1 taken 193 times.
42178 if (table->file->get_lock_type() != F_UNLCK)
1638
1/2
✓ Branch 0 taken 41985 times.
✗ Branch 1 not taken.
41985 table->file->ha_external_lock(thd, F_UNLCK);
1639
1/2
✓ Branch 0 taken 42178 times.
✗ Branch 1 not taken.
42178 close_thread_table(thd, prev);
1640 42178 continue;
1641 }
1642 }
1643 }
1644 900082 prev = &table->next;
1645 } // End of for
1646 }
1647
1648 /* Ensure we are calling ha_reset() for all used tables */
1649
1/2
✓ Branch 0 taken 3035539 times.
✗ Branch 1 not taken.
3035539 mark_used_tables_as_free_for_reuse(thd, thd->open_tables);
1650
1651 /*
1652 Mark this statement as one that has "unlocked" its tables.
1653 For purposes of Query_tables_list::lock_tables_state we treat
1654 any statement which passed through close_thread_tables() as
1655 such.
1656 */
1657 3035539 thd->lex->lock_tables_state = Query_tables_list::LTS_NOT_LOCKED;
1658
1659 /*
1660 We are under simple LOCK TABLES or we're inside a sub-statement
1661 of a prelocked statement, so should not do anything else.
1662
1663 Note that even if we are in LTM_LOCK_TABLES mode and statement
1664 requires prelocking (e.g. when we are closing tables after
1665 failing to "open" all tables required for statement execution)
1666 we will exit this function a few lines below.
1667 */
1668
2/2
✓ Branch 0 taken 701723 times.
✓ Branch 1 taken 2333816 times.
3035539 if (!thd->lex->requires_prelocking()) return;
1669
1670 /*
1671 We are in the top-level statement of a prelocked statement,
1672 so we have to leave the prelocked mode now with doing implicit
1673 UNLOCK TABLES if needed.
1674 */
1675
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 2333752 times.
2333816 if (thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES)
1676 64 thd->locked_tables_mode = LTM_LOCK_TABLES;
1677
1678
2/2
✓ Branch 0 taken 195 times.
✓ Branch 1 taken 2333621 times.
2333816 if (thd->locked_tables_mode == LTM_LOCK_TABLES) return;
1679
1680
1/2
✓ Branch 0 taken 2333621 times.
✗ Branch 1 not taken.
2333621 thd->leave_locked_tables_mode();
1681
1682 /* Fallthrough */
1683 }
1684
1685
2/2
✓ Branch 0 taken 40937934 times.
✓ Branch 1 taken 22906938 times.
63844872 if (thd->lock) {
1686 /*
1687 For RBR we flush the pending event just before we unlock all the
1688 tables. This means that we are at the end of a topmost
1689 statement, so we ensure that the STMT_END_F flag is set on the
1690 pending event. For statements that are *inside* stored
1691 functions, the pending event will not be flushed: that will be
1692 handled either before writing a query log event (inside
1693 binlog_query()) or when preparing a pending event.
1694 */
1695
1/2
✓ Branch 0 taken 40938826 times.
✗ Branch 1 not taken.
40937934 (void)thd->binlog_flush_pending_rows_event(true);
1696
1/2
✓ Branch 0 taken 40938725 times.
✗ Branch 1 not taken.
40938826 mysql_unlock_tables(thd, thd->lock);
1697 40938725 thd->lock = nullptr;
1698 }
1699
1700 63845663 thd->lex->lock_tables_state = Query_tables_list::LTS_NOT_LOCKED;
1701
1702 /*
1703 Closing a MERGE child before the parent would be fatal if the
1704 other thread tries to abort the MERGE lock in between.
1705 */
1706
3/4
✓ Branch 0 taken 40655196 times.
✓ Branch 1 taken 23190467 times.
✓ Branch 2 taken 40654317 times.
✗ Branch 3 not taken.
63845663 if (thd->open_tables) close_open_tables(thd);
1707
2/2
✓ Branch 0 taken 63845791 times.
✓ Branch 1 taken 701903 times.
64546702 }
1708
1709 /**
1710 Helper function which returns TABLE to Table Cache or closes if
1711 table is marked as needing re-open.
1712 */
1713 117479628 static void release_or_close_table(THD *thd, TABLE *table) {
1714 117479628 Table_cache *tc = table_cache_manager.get_cache(thd);
1715
1716 117479746 tc->lock();
1717
1718
2/2
✓ Branch 0 taken 117129529 times.
✓ Branch 1 taken 259302 times.
234868332 if (table->s->has_old_version() || table->has_invalid_dict() ||
1719
8/8
✓ Branch 0 taken 117388623 times.
✓ Branch 1 taken 91253 times.
✓ Branch 2 taken 117128396 times.
✓ Branch 3 taken 615 times.
✓ Branch 4 taken 913 times.
✓ Branch 5 taken 117127483 times.
✓ Branch 6 taken 352083 times.
✓ Branch 7 taken 117127483 times.
234868707 table->has_invalid_stats() || table_def_shutdown_in_progress) {
1720 352083 tc->remove_table(table);
1721 352083 mysql_mutex_lock(&LOCK_open);
1722 352083 intern_close_table(table);
1723 352083 mysql_mutex_unlock(&LOCK_open);
1724 } else
1725 117127483 tc->release_table(thd, table);
1726
1727 117480147 tc->unlock();
1728 117480457 }
1729
1730 /* move one table to free list */
1731
1732 117480136 void close_thread_table(THD *thd, TABLE **table_ptr) {
1733 117480136 TABLE *table = *table_ptr;
1734
1/2
✓ Branch 0 taken 117480185 times.
✗ Branch 1 not taken.
117480136 DBUG_TRACE;
1735
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117480185 times.
117480185 assert(table->key_read == 0);
1736
3/4
✓ Branch 0 taken 117480150 times.
✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 117480150 times.
117480185 assert(!table->file || table->file->inited == handler::NONE);
1737 117480185 mysql_mutex_assert_not_owner(&LOCK_open);
1738 /*
1739 The metadata lock must be released after giving back
1740 the table to the table cache.
1741 */
1742
2/4
✓ Branch 0 taken 117479835 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 117479835 times.
117480399 assert(thd->mdl_context.owns_equal_or_stronger_lock(
1743 MDL_key::TABLE, table->s->db.str, table->s->table_name.str, MDL_SHARED));
1744 117479835 table->mdl_ticket = nullptr;
1745 117479835 table->pos_in_table_list = nullptr;
1746
1747
1/2
✓ Branch 0 taken 117479618 times.
✗ Branch 1 not taken.
117479835 mysql_mutex_lock(&thd->LOCK_thd_data);
1748
1749
5/6
✓ Branch 0 taken 141796 times.
✓ Branch 1 taken 117337822 times.
✓ Branch 2 taken 141796 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 141796 times.
✓ Branch 5 taken 117337528 times.
117479618 if (unlikely(opt_userstat && table->file)) {
1750
1/2
✓ Branch 0 taken 141796 times.
✗ Branch 1 not taken.
141796 table->file->update_global_table_stats();
1751
1/2
✓ Branch 0 taken 141796 times.
✗ Branch 1 not taken.
141796 table->file->update_global_index_stats();
1752 }
1753
1754 117479324 *table_ptr = table->next;
1755
1/2
✓ Branch 0 taken 117479908 times.
✗ Branch 1 not taken.
117479324 mysql_mutex_unlock(&thd->LOCK_thd_data);
1756
1757 /*
1758 It is not safe to call the below code for TABLE objects for which
1759 handler::open() has not been called (for example, we use such objects
1760 while updating information about views which depend on table being
1761 ALTERed). Another possibly unsafe case is when TABLE/handler object
1762 has been marked as invalid (for example, it is unsafe to call
1763 handler::reset() for partitioned InnoDB tables after in-place ALTER
1764 TABLE API commit phase).
1765 */
1766
3/4
✓ Branch 0 taken 117479573 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117216959 times.
✓ Branch 3 taken 262614 times.
117479908 if (!table->has_invalid_dict()) {
1767 /* Avoid having MERGE tables with attached children in unused_tables. */
1768
1/2
✓ Branch 0 taken 117217432 times.
✗ Branch 1 not taken.
117216959 table->file->ha_extra(HA_EXTRA_DETACH_CHILDREN);
1769 /* Free memory and reset for next loop. */
1770
1/2
✓ Branch 0 taken 117216825 times.
✗ Branch 1 not taken.
117217432 free_blob_buffers_and_reset(table, MAX_TDC_BLOB_SIZE);
1771
1/2
✓ Branch 0 taken 117217396 times.
✗ Branch 1 not taken.
117216825 table->file->ha_reset();
1772 }
1773
1774 /* Do this *before* entering the LOCK_open critical section. */
1775
2/4
✓ Branch 0 taken 117480051 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 117479663 times.
✗ Branch 3 not taken.
117480010 if (table->file != nullptr) table->file->unbind_psi();
1776
1777
1/2
✓ Branch 0 taken 117480278 times.
✗ Branch 1 not taken.
117479622 release_or_close_table(thd, table);
1778 117480278 }
1779
1780 /* close_temporary_tables' internal, 4 is due to uint4korr definition */
1781 1875 static inline uint tmpkeyval(TABLE *table) {
1782 1875 return uint4korr(table->s->table_cache_key.str +
1783 1875 table->s->table_cache_key.length - 4);
1784 }
1785
1786 /*
1787 Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1788 creates one DROP TEMPORARY TABLE binlog event for each pseudo-thread.
1789
1790 TODO: In future, we should have temporary_table= 0 and
1791 replica_open_temp_tables.fetch_add() at one place instead of repeating
1792 it all across the function. An alternative would be to use
1793 close_temporary_table() instead of close_temporary() that maintains
1794 the correct invariant regarding empty list of temporary tables
1795 and zero replica_open_temp_tables already.
1796 */
1797
1798 1329332 bool close_temporary_tables(THD *thd) {
1799
1/2
✓ Branch 0 taken 1329950 times.
✗ Branch 1 not taken.
1329332 DBUG_TRACE;
1800 TABLE *table;
1801 1329950 TABLE *next = nullptr;
1802 TABLE *prev_table;
1803 /* Assume thd->variables.option_bits has OPTION_QUOTE_SHOW_CREATE */
1804 1329950 bool was_quote_show = true;
1805 1329950 bool error = false;
1806 1329950 int slave_closed_temp_tables = 0;
1807
1808
2/2
✓ Branch 0 taken 1328854 times.
✓ Branch 1 taken 1096 times.
1329950 if (!thd->temporary_tables) return false;
1809
1810
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1092 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
1096 assert(!thd->slave_thread ||
1811 thd->system_thread != SYSTEM_THREAD_SLAVE_WORKER);
1812
1813 /*
1814 Ensure we don't have open HANDLERs for tables we are about to close.
1815 This is necessary when close_temporary_tables() is called as part
1816 of execution of BINLOG statement (e.g. for format description event).
1817 */
1818
1/2
✓ Branch 0 taken 1096 times.
✗ Branch 1 not taken.
1096 mysql_ha_rm_temporary_tables(thd);
1819
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1095 times.
1096 if (!mysql_bin_log.is_open()) {
1820 TABLE *tmp_next;
1821
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 mysql_mutex_lock(&thd->LOCK_temporary_tables);
1822
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for (TABLE *t = thd->temporary_tables; t; t = tmp_next) {
1823 1 tmp_next = t->next;
1824
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 mysql_lock_remove(thd, thd->lock, t);
1825 /*
1826 We should not meet temporary tables created by ALTER TABLE here.
1827 It is responsibility of ALTER statement to close them. Otherwise
1828 it might be necessary to remove them from DD as well.
1829 */
1830
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 assert(t->s->tmp_table_def);
1831
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 close_temporary(thd, t, true, true);
1832 1 slave_closed_temp_tables++;
1833 }
1834
1835 1 thd->temporary_tables = nullptr;
1836
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 mysql_mutex_unlock(&thd->LOCK_temporary_tables);
1837
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (thd->slave_thread) {
1838 atomic_replica_open_temp_tables -= slave_closed_temp_tables;
1839 thd->rli_slave->get_c_rli()->atomic_channel_open_temp_tables -=
1840 slave_closed_temp_tables;
1841 }
1842
1843 1 return false;
1844 }
1845
1846 /*
1847 We are about to generate DROP TEMPORARY TABLE statements for all
1848 the left out temporary tables. If GTID_NEXT is set (e.g. if user
1849 did SET GTID_NEXT just before disconnecting the client), we must
1850 ensure that it will be able to generate GTIDs for the statements
1851 with this server's UUID. Therefore we set gtid_next to
1852 AUTOMATIC_GTID.
1853 */
1854
1/2
✓ Branch 0 taken 1093 times.
✗ Branch 1 not taken.
1095 gtid_state->update_on_rollback(thd);
1855 1093 thd->variables.gtid_next.set_automatic();
1856
1857 /*
1858 We must separate transactional temp tables and
1859 non-transactional temp tables in two distinct DROP statements
1860 to avoid the splitting if a slave server reads from this binlog.
1861 */
1862
1863 /* Better add "if exists", in case a RESET MASTER has been done */
1864 1093 const char stub[] = "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ";
1865 1093 uint stub_len = sizeof(stub) - 1;
1866 char buf_trans[256], buf_non_trans[256];
1867 String s_query_trans =
1868 1093 String(buf_trans, sizeof(buf_trans), system_charset_info);
1869 String s_query_non_trans =
1870 1094 String(buf_non_trans, sizeof(buf_non_trans), system_charset_info);
1871 1095 bool found_user_tables = false;
1872 1095 bool found_trans_table = false;
1873 1095 bool found_non_trans_table = false;
1874
1875 1095 memcpy(buf_trans, stub, stub_len);
1876 1095 memcpy(buf_non_trans, stub, stub_len);
1877
1878 /*
1879 Insertion sort of temp tables by pseudo_thread_id to build ordered list
1880 of sublists of equal pseudo_thread_id
1881 */
1882
1/2
✓ Branch 0 taken 1095 times.
✗ Branch 1 not taken.
1095 mysql_mutex_lock(&thd->LOCK_temporary_tables);
1883
1884
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 1095 times.
1348 for (prev_table = thd->temporary_tables, table = prev_table->next; table;
1885 253 prev_table = table, table = table->next) {
1886 TABLE *prev_sorted /* same as for prev_table */, *sorted;
1887 /*
1888 We should not meet temporary tables created by ALTER TABLE here.
1889 It is responsibility of ALTER statement to close them. Otherwise
1890 it might be necessary to remove them from DD as well.
1891 */
1892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 253 times.
253 assert(table->s->tmp_table_def);
1893
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 3 times.
253 if (is_user_table(table)) {
1894
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 172 times.
250 if (!found_user_tables) found_user_tables = true;
1895 250 for (prev_sorted = nullptr, sorted = thd->temporary_tables;
1896
2/2
✓ Branch 0 taken 864 times.
✓ Branch 1 taken 226 times.
1090 sorted != table; prev_sorted = sorted, sorted = sorted->next) {
1897
6/6
✓ Branch 0 taken 858 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 840 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 840 times.
864 if (!is_user_table(sorted) || tmpkeyval(sorted) > tmpkeyval(table)) {
1898 /* move into the sorted part of the list from the unsorted */
1899 24 prev_table->next = table->next;
1900 24 table->next = sorted;
1901
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 11 times.
24 if (prev_sorted) {
1902 13 prev_sorted->next = table;
1903 } else {
1904 11 thd->temporary_tables = table;
1905 }
1906 24 table = prev_table;
1907 24 break;
1908 }
1909 }
1910 }
1911 }
1912
1913 /* We always quote db,table names though it is slight overkill */
1914
4/6
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 1017 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 78 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1095 times.
1095 if (found_user_tables && !(was_quote_show = (thd->variables.option_bits &
1915 OPTION_QUOTE_SHOW_CREATE))) {
1916 thd->variables.option_bits |= OPTION_QUOTE_SHOW_CREATE;
1917 }
1918
1919 /*
1920 Make LEX consistent with DROP TEMPORARY TABLES statement which we
1921 are going to log. This is important for the binary logging code.
1922 */
1923 1095 LEX *lex = thd->lex;
1924 1095 enum_sql_command sav_sql_command = lex->sql_command;
1925 1095 bool sav_drop_temp = lex->drop_temporary;
1926 1095 lex->sql_command = SQLCOM_DROP_TABLE;
1927 1095 lex->drop_temporary = true;
1928
1929 /* scan sorted tmps to generate sequence of DROP */
1930
2/2
✓ Branch 0 taken 1324 times.
✓ Branch 1 taken 1097 times.
2421 for (table = thd->temporary_tables; table; table = next) {
1931
7/8
✓ Branch 0 taken 1319 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1319 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 62 times.
✓ Branch 5 taken 1257 times.
✓ Branch 6 taken 62 times.
✓ Branch 7 taken 1263 times.
1324 if (is_user_table(table) && table->should_binlog_drop_if_temp()) {
1932 62 bool save_thread_specific_used = thd->thread_specific_used;
1933 62 my_thread_id save_pseudo_thread_id = thd->variables.pseudo_thread_id;
1934 /* Set pseudo_thread_id to be that of the processed table */
1935 62 thd->variables.pseudo_thread_id = tmpkeyval(table);
1936 62 String db;
1937
1/2
✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
62 db.append(table->s->db.str);
1938 /* Loop forward through all tables that belong to a common database
1939 within the sublist of common pseudo_thread_id to create single
1940 DROP query
1941 */
1942 62 for (s_query_trans.length(stub_len), s_query_non_trans.length(stub_len),
1943 62 found_trans_table = false, found_non_trans_table = false;
1944
2/2
✓ Branch 0 taken 97 times.
✓ Branch 1 taken 1 times.
98 table && is_user_table(table) &&
1945
4/4
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 4 times.
190 tmpkeyval(table) == thd->variables.pseudo_thread_id &&
1946
4/4
✓ Branch 0 taken 98 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 62 times.
337 table->s->db.length == db.length() &&
1947
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 5 times.
89 strcmp(table->s->db.str, db.ptr()) == 0;
1948 84 table = next) {
1949 /* Separate transactional from non-transactional temp tables */
1950
2/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 84 times.
✗ Branch 3 not taken.
84 if (table->should_binlog_drop_if_temp()) {
1951 /* Separate transactional from non-transactional temp tables */
1952
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 14 times.
84 if (table->s->tmp_table == TRANSACTIONAL_TMP_TABLE) {
1953 70 found_trans_table = true;
1954 /*
1955 We are going to add ` around the table names and possible more
1956 due to special characters
1957 */
1958 70 append_identifier(thd, &s_query_trans, table->s->table_name.str,
1959
1/2
✓ Branch 0 taken 70 times.
✗ Branch 1 not taken.
70 strlen(table->s->table_name.str));
1960
1/2
✓ Branch 0 taken 70 times.
✗ Branch 1 not taken.
70 s_query_trans.append(',');
1961
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 } else if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE) {
1962 14 found_non_trans_table = true;
1963 /*
1964 We are going to add ` around the table names and possible more
1965 due to special characters
1966 */
1967 14 append_identifier(thd, &s_query_non_trans, table->s->table_name.str,
1968
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 strlen(table->s->table_name.str));
1969
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 s_query_non_trans.append(',');
1970 }
1971 }
1972
1973 84 next = table->next;
1974
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 mysql_lock_remove(thd, thd->lock, table);
1975
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 close_temporary(thd, table, true, true);
1976 84 slave_closed_temp_tables++;
1977 }
1978
1/2
✓ Branch 0 taken 62 times.
✗ Branch 1 not taken.
62 thd->clear_error();
1979 62 const CHARSET_INFO *cs_save = thd->variables.character_set_client;
1980 62 thd->variables.character_set_client = system_charset_info;
1981 62 thd->thread_specific_used = true;
1982
1983
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 6 times.
62 if (found_trans_table) {
1984 56 Query_log_event qinfo(thd, s_query_trans.ptr(),
1985 56 s_query_trans.length() - 1, false, true, false,
1986
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 0);
1987 56 qinfo.db = db.ptr();
1988 56 qinfo.db_len = db.length();
1989 56 thd->variables.character_set_client = cs_save;
1990
1991 56 thd->get_stmt_da()->set_overwrite_status(true);
1992
2/4
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 56 times.
112 if ((error = (mysql_bin_log.write_event(&qinfo) ||
1993
4/8
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 56 times.
56 mysql_bin_log.commit(thd, true) || error))) {
1994 /*
1995 If we're here following THD::cleanup, thence the connection
1996 has been closed already. So lets print a message to the
1997 error log instead of pushing yet another error into the
1998 Diagnostics_area.
1999
2000 Also, we keep the error flag so that we propagate the error
2001 up in the stack. This way, if we're the SQL thread we notice
2002 that close_temporary_tables failed. (Actually, the SQL
2003 thread only calls close_temporary_tables while applying old
2004 Start_log_event_v3 events.)
2005 */
2006 LogErr(ERROR_LEVEL, ER_BINLOG_FAILED_TO_WRITE_DROP_FOR_TEMP_TABLES);
2007 }
2008 56 thd->get_stmt_da()->set_overwrite_status(false);
2009 56 }
2010
2011
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 52 times.
62 if (found_non_trans_table) {
2012 10 Query_log_event qinfo(thd, s_query_non_trans.ptr(),
2013 10 s_query_non_trans.length() - 1, false, true,
2014
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 false, 0);
2015 10 qinfo.db = db.ptr();
2016 10 qinfo.db_len = db.length();
2017 10 thd->variables.character_set_client = cs_save;
2018
2019 10 thd->get_stmt_da()->set_overwrite_status(true);
2020
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
20 if ((error = (mysql_bin_log.write_event(&qinfo) ||
2021
4/8
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 times.
10 mysql_bin_log.commit(thd, true) || error))) {
2022 /*
2023 If we're here following THD::cleanup, thence the connection
2024 has been closed already. So lets print a message to the
2025 error log instead of pushing yet another error into the
2026 Diagnostics_area.
2027
2028 Also, we keep the error flag so that we propagate the error
2029 up in the stack. This way, if we're the SQL thread we notice
2030 that close_temporary_tables failed. (Actually, the SQL
2031 thread only calls close_temporary_tables while applying old
2032 Start_log_event_v3 events.)
2033 */
2034 LogErr(ERROR_LEVEL, ER_BINLOG_FAILED_TO_WRITE_DROP_FOR_TEMP_TABLES);
2035 }
2036 10 thd->get_stmt_da()->set_overwrite_status(false);
2037 10 }
2038
2039 62 thd->variables.pseudo_thread_id = save_pseudo_thread_id;
2040 62 thd->thread_specific_used = save_thread_specific_used;
2041 62 } else {
2042 1263 next = table->next;
2043 /*
2044 This is for those cases when we have acquired lock but drop temporary
2045 table will not be logged.
2046 */
2047
1/2
✓ Branch 0 taken 1262 times.
✗ Branch 1 not taken.
1263 mysql_lock_remove(thd, thd->lock, table);
2048
1/2
✓ Branch 0 taken 1264 times.
✗ Branch 1 not taken.
1262 close_temporary(thd, table, true, true);
2049 1264 slave_closed_temp_tables++;
2050 }
2051 }
2052 1097 thd->temporary_tables = nullptr;
2053
1/2
✓ Branch 0 taken 1095 times.
✗ Branch 1 not taken.
1097 mysql_mutex_unlock(&thd->LOCK_temporary_tables);
2054 1095 lex->drop_temporary = sav_drop_temp;
2055 1095 lex->sql_command = sav_sql_command;
2056
2057
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1095 times.
1095 if (!was_quote_show)
2058 thd->variables.option_bits &=
2059 ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
2060
2061
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1091 times.
1095 if (thd->slave_thread) {
2062 4 atomic_replica_open_temp_tables -= slave_closed_temp_tables;
2063
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 thd->rli_slave->get_c_rli()->atomic_channel_open_temp_tables -=
2064 slave_closed_temp_tables;
2065 }
2066
2067 1095 return error;
2068 1329950 }
2069
2070 /**
2071 Find table in global list.
2072
2073 @param table Pointer to table list
2074 @param db_name Data base name
2075 @param table_name Table name
2076
2077 @returns Pointer to found table.
2078 @retval NULL Table not found
2079 */
2080
2081 9715397 TABLE_LIST *find_table_in_global_list(TABLE_LIST *table, const char *db_name,
2082 const char *table_name) {
2083
2/2
✓ Branch 0 taken 500189 times.
✓ Branch 1 taken 9378555 times.
9878744 for (; table; table = table->next_global) {
2084
2/2
✓ Branch 0 taken 495140 times.
✓ Branch 1 taken 5049 times.
500189 if ((table->table == nullptr ||
2085
2/2
✓ Branch 0 taken 491268 times.
✓ Branch 1 taken 3872 times.
495140 table->table->s->tmp_table == NO_TMP_TABLE) &&
2086
2/2
✓ Branch 0 taken 392322 times.
✓ Branch 1 taken 103995 times.
496317 strcmp(table->db, db_name) == 0 &&
2087
2/2
✓ Branch 0 taken 336842 times.
✓ Branch 1 taken 55480 times.
392322 strcmp(table->table_name, table_name) == 0)
2088 336842 break;
2089 }
2090 9715397 return table;
2091 }
2092
2093 /**
2094 Test that table is unique (It's only exists once in the table list)
2095
2096 @param table table to be checked (must be updatable base table)
2097 @param table_list list of tables
2098 @param check_alias whether to check tables' aliases
2099
2100 NOTE: to exclude derived tables from check we use following mechanism:
2101 a) during derived table processing set THD::derived_tables_processing
2102 b) Query_block::prepare set SELECT::exclude_from_table_unique_test if
2103 THD::derived_tables_processing set. (we can't use JOIN::execute
2104 because for PS we perform only Query_block::prepare, but we can't set
2105 this flag in Query_block::prepare if we are not sure that we are in
2106 derived table processing loop, because multi-update call fix_fields()
2107 for some its items (which mean Query_block::prepare for subqueries)
2108 before unique_table call to detect which tables should be locked for
2109 write).
2110 c) find_dup_table skip all tables which belong to SELECT with
2111 SELECT::exclude_from_table_unique_test set.
2112 Also SELECT::exclude_from_table_unique_test used to exclude from check
2113 tables of main SELECT of multi-delete and multi-update
2114
2115 We also skip tables with TABLE_LIST::prelocking_placeholder set,
2116 because we want to allow SELECTs from them, and their modification
2117 will rise the error anyway.
2118
2119 TODO: when we will have table/view change detection we can do this check
2120 only once for PS/SP
2121
2122 @retval !=0 found duplicate
2123 @retval 0 if table is unique
2124 */
2125
2126 9485676 static TABLE_LIST *find_dup_table(const TABLE_LIST *table,
2127 TABLE_LIST *table_list, bool check_alias) {
2128 TABLE_LIST *res;
2129 const char *d_name, *t_name, *t_alias;
2130
1/2
✓ Branch 0 taken 9486539 times.
✗ Branch 1 not taken.
9485676 DBUG_TRACE;
2131
5/8
✓ Branch 0 taken 9486460 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9486536 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 9486521 times.
✓ Branch 6 taken 15 times.
✗ Branch 7 not taken.
9486539 DBUG_PRINT("enter", ("table alias: %s", table->alias));
2132
2133
2/4
✓ Branch 0 taken 9486564 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9486564 times.
9486536 assert(table == table->updatable_base_table());
2134 /*
2135 If this function called for CREATE command that we have not opened table
2136 (table->table equal to 0) and right names is in current TABLE_LIST
2137 object.
2138 */
2139
2/2
✓ Branch 0 taken 9486552 times.
✓ Branch 1 taken 12 times.
9486564 if (table->table) {
2140 /* All MyISAMMRG children are plain MyISAM tables. */
2141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9486552 times.
9486552 assert(table->table->file->ht->db_type != DB_TYPE_MRG_MYISAM);
2142
2143 /* temporary table is always unique */
2144
2/2
✓ Branch 0 taken 132880 times.
✓ Branch 1 taken 9353672 times.
9486552 if (table->table->s->tmp_table != NO_TMP_TABLE) return nullptr;
2145 }
2146
2147 9353684 d_name = table->db;
2148 9353684 t_name = table->table_name;
2149 9353684 t_alias = table->alias;
2150
2151
5/8
✓ Branch 0 taken 9353426 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9353672 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 9353657 times.
✓ Branch 6 taken 38 times.
✗ Branch 7 not taken.
9353684 DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name));
2152 for (;;) {
2153 /*
2154 Table is unique if it is present only once in the global list
2155 of tables and once in the list of table locks.
2156 */
2157
3/4
✓ Branch 0 taken 9682471 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9345743 times.
✓ Branch 3 taken 336728 times.
9683075 if (!(res = find_table_in_global_list(table_list, d_name, t_name))) break;
2158
2159 /* Skip if same underlying table. */
2160
3/4
✓ Branch 0 taken 336827 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 324647 times.
✓ Branch 3 taken 12180 times.
336728 if (res->table && (res->table == table->table)) goto next;
2161
2162 /* Skip if table alias does not match. */
2163
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 12035 times.
12081 if (check_alias) {
2164 92 if (lower_case_table_names
2165
5/6
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 33 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 44 times.
79 ? my_strcasecmp(files_charset_info, t_alias, res->alias)
2166 33 : strcmp(t_alias, res->alias))
2167 2 goto next;
2168 }
2169
2170 /*
2171 Skip if marked to be excluded (could be a derived table) or if
2172 entry is a prelocking placeholder.
2173 */
2174
3/4
✓ Branch 0 taken 12124 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4679 times.
✓ Branch 3 taken 7445 times.
12079 if (res->query_block && !res->query_block->exclude_from_table_unique_test &&
2175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7445 times.
7445 !res->prelocking_placeholder)
2176 7445 break;
2177
2178 /*
2179 If we found entry of this table or table of SELECT which already
2180 processed in derived table or top select of multi-update/multi-delete
2181 (exclude_from_table_unique_test) or prelocking placeholder.
2182 */
2183 4634 next:
2184 329283 table_list = res->next_global;
2185
5/8
✓ Branch 0 taken 329379 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 329380 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 329376 times.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
329283 DBUG_PRINT("info",
2186 ("found same copy of table or table which we should skip"));
2187 }
2188 9353188 return res;
2189 9486068 }
2190
2191 /**
2192 Test that the subject table of INSERT/UPDATE/DELETE/CREATE
2193 or (in case of MyISAMMRG) one of its children are not used later
2194 in the query.
2195
2196 For MyISAMMRG tables, it is assumed that all the underlying
2197 tables of @c table (if any) are listed right after it and that
2198 their @c parent_l field points at the main table.
2199
2200 @param table table to be checked (must be updatable base table)
2201 @param table_list List of tables to check against
2202 @param check_alias whether to check tables' aliases
2203
2204 @retval non-NULL The table list element for the table that
2205 represents the duplicate.
2206 @retval NULL No duplicates found.
2207 */
2208
2209 9484477 TABLE_LIST *unique_table(const TABLE_LIST *table, TABLE_LIST *table_list,
2210 bool check_alias) {
2211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9485289 times.
9484477 assert(table == table->updatable_base_table());
2212
2213 TABLE_LIST *dup;
2214
3/4
✓ Branch 0 taken 9485327 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1200 times.
✓ Branch 3 taken 9484127 times.
9485289 if (table->table && table->table->file->ht->db_type == DB_TYPE_MRG_MYISAM) {
2215 TABLE_LIST *child;
2216 1200 dup = nullptr;
2217 /* Check duplicates of all merge children. */
2218
4/4
✓ Branch 0 taken 2487 times.
✓ Branch 1 taken 1062 times.
✓ Branch 2 taken 2361 times.
✓ Branch 3 taken 126 times.
3549 for (child = table->next_global; child && child->parent_l == table;
2219 2349 child = child->next_global) {
2220
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2349 times.
2361 if ((dup = find_dup_table(child, child->next_global, check_alias))) break;
2221 }
2222 1200 } else
2223 9484089 dup = find_dup_table(table, table_list, check_alias);
2224 9485175 return dup;
2225 }
2226
2227 /**
2228 Issue correct error message in case we found 2 duplicate tables which
2229 prevent some update operation
2230
2231 @param update table which we try to update
2232 @param operation name of update operation
2233 @param duplicate duplicate table which we found
2234
2235 @note here we hide view underlying tables if we have them.
2236 */
2237
2238 76 void update_non_unique_table_error(TABLE_LIST *update, const char *operation,
2239 TABLE_LIST *duplicate) {
2240 76 update = update->top_table();
2241 76 duplicate = duplicate->top_table();
2242
4/4
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 13 times.
154 if (!update->is_view() || !duplicate->is_view() ||
2243 34 update->view_query() == duplicate->view_query() ||
2244
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 update->table_name_length != duplicate->table_name_length ||
2245
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 update->db_length != duplicate->db_length ||
2246
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12 times.
21 my_strcasecmp(table_alias_charset, update->table_name,
2247
4/4
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 67 times.
✓ Branch 3 taken 9 times.
120 duplicate->table_name) != 0 ||
2248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 my_strcasecmp(table_alias_charset, update->db, duplicate->db) != 0) {
2249 /*
2250 it is not the same view repeated (but it can be parts of the same copy
2251 of view), so we have to hide underlying tables.
2252 */
2253
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 32 times.
67 if (update->is_view()) {
2254 // Issue the ER_NON_INSERTABLE_TABLE error for an INSERT
2255
6/6
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 12 times.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 22 times.
60 if (duplicate->is_view() &&
2256 25 update->view_query() == duplicate->view_query())
2257
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 10 times.
13 my_error(!strncmp(operation, "INSERT", 6) ? ER_NON_INSERTABLE_TABLE
2258 : ER_NON_UPDATABLE_TABLE,
2259 MYF(0), update->alias, operation);
2260 else
2261
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 10 times.
22 my_error(ER_VIEW_PREVENT_UPDATE, MYF(0),
2262 22 (duplicate->is_view() ? duplicate->alias : update->alias),
2263 operation, update->alias);
2264 35 return;
2265 }
2266
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 20 times.
32 if (duplicate->is_view()) {
2267 12 my_error(ER_VIEW_PREVENT_UPDATE, MYF(0), duplicate->alias, operation,
2268 update->alias);
2269 12 return;
2270 }
2271 }
2272 29 my_error(ER_UPDATE_TABLE_USED, MYF(0), update->alias);
2273 }
2274
2275 /**
2276 Find temporary table specified by database and table names in the
2277 THD::temporary_tables list.
2278
2279 @return TABLE instance if a temporary table has been found; NULL otherwise.
2280 */
2281
2282 177957 TABLE *find_temporary_table(THD *thd, const char *db, const char *table_name) {
2283 char key[MAX_DBKEY_LENGTH];
2284
1/2
✓ Branch 0 taken 177957 times.
✗ Branch 1 not taken.
177957 size_t key_length = create_table_def_key_tmp(thd, db, table_name, key);
2285 355914 return find_temporary_table(thd, key, key_length);
2286 }
2287
2288 /**
2289 Find a temporary table specified by TABLE_LIST instance in the
2290 THD::temporary_tables list.
2291
2292 @return TABLE instance if a temporary table has been found; NULL otherwise.
2293 */
2294
2295 18458000 TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl) {
2296 const char *key;
2297 size_t key_length;
2298 char key_suffix[TMP_TABLE_KEY_EXTRA];
2299 TABLE *table;
2300
2301
1/2
✓ Branch 0 taken 18458628 times.
✗ Branch 1 not taken.
18458000 key_length = get_table_def_key(tl, &key);
2302
2303 18458628 int4store(key_suffix, thd->server_id);
2304 18458486 int4store(key_suffix + 4, thd->variables.pseudo_thread_id);
2305
2306
2/2
✓ Branch 0 taken 2026091 times.
✓ Branch 1 taken 18152362 times.
20178453 for (table = thd->temporary_tables; table; table = table->next) {
2307 2026091 if ((table->s->table_cache_key.length ==
2308
2/2
✓ Branch 0 taken 1292816 times.
✓ Branch 1 taken 733275 times.
2026091 key_length + TMP_TABLE_KEY_EXTRA) &&
2309
2/2
✓ Branch 0 taken 306121 times.
✓ Branch 1 taken 986695 times.
1292816 !memcmp(table->s->table_cache_key.str, key, key_length) &&
2310
2/2
✓ Branch 0 taken 306101 times.
✓ Branch 1 taken 20 times.
306121 !memcmp(table->s->table_cache_key.str + key_length, key_suffix,
2311 TMP_TABLE_KEY_EXTRA))
2312 306101 return table;
2313 }
2314 18152362 return nullptr;
2315 }
2316
2317 /**
2318 Find a temporary table specified by a key in the THD::temporary_tables list.
2319
2320 @return TABLE instance if a temporary table has been found; NULL otherwise.
2321 */
2322
2323 177957 static TABLE *find_temporary_table(THD *thd, const char *table_key,
2324 size_t table_key_length) {
2325
2/2
✓ Branch 0 taken 739659 times.
✓ Branch 1 taken 177884 times.
917543 for (TABLE *table = thd->temporary_tables; table; table = table->next) {
2326
2/2
✓ Branch 0 taken 452170 times.
✓ Branch 1 taken 287489 times.
739659 if (table->s->table_cache_key.length == table_key_length &&
2327
2/2
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 452097 times.
452170 !memcmp(table->s->table_cache_key.str, table_key, table_key_length)) {
2328 73 return table;
2329 }
2330 }
2331
2332 177884 return nullptr;
2333 }
2334
2335 /**
2336 Drop a temporary table.
2337
2338 - If the table is locked with LOCK TABLES or by prelocking,
2339 unlock it and remove it from the list of locked tables
2340 (THD::lock). Currently only transactional temporary tables
2341 are locked.
2342 - Close the temporary table.
2343 - Remove the table from the list of temporary tables.
2344 */
2345
2346 49809 void drop_temporary_table(THD *thd, TABLE_LIST *table_list) {
2347
1/2
✓ Branch 0 taken 49809 times.
✗ Branch 1 not taken.
49809 DBUG_TRACE;
2348
3/8
✓ Branch 0 taken 49809 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49809 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 49809 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
49809 DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'", table_list->db,
2349 table_list->table_name));
2350
2351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49809 times.
49809 assert(is_temporary_table(table_list));
2352
2353 49809 TABLE *table = table_list->table;
2354
2355
2/4
✓ Branch 0 taken 49809 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 49809 times.
49809 assert(!table->query_id || table->query_id == thd->query_id);
2356
2357 /*
2358 If LOCK TABLES list is not empty and contains this table,
2359 unlock the table and remove the table from this list.
2360 */
2361
1/2
✓ Branch 0 taken 49809 times.
✗ Branch 1 not taken.
49809 mysql_lock_remove(thd, thd->lock, table);
2362
1/2
✓ Branch 0 taken 49809 times.
✗ Branch 1 not taken.
49809 close_temporary_table(thd, table, true, true);
2363 49809 table_list->table = nullptr;
2364 49809 }
2365
2366 /*
2367 unlink from thd->temporary tables and close temporary table
2368 */
2369
2370 144897 void close_temporary_table(THD *thd, TABLE *table, bool free_share,
2371 bool delete_table) {
2372
1/2
✓ Branch 0 taken 144897 times.
✗ Branch 1 not taken.
144897 DBUG_TRACE;
2373
5/8
✓ Branch 0 taken 144897 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144897 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 144896 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
144897 DBUG_PRINT("tmptable",
2374 ("closing table: '%s'.'%s' %p alias: '%s'", table->s->db.str,
2375 table->s->table_name.str, table, table->alias));
2376
2377
1/2
✓ Branch 0 taken 144897 times.
✗ Branch 1 not taken.
144897 mysql_mutex_lock(&thd->LOCK_temporary_tables);
2378
2379
2/2
✓ Branch 0 taken 4961 times.
✓ Branch 1 taken 139936 times.
144897 if (table->prev) {
2380 4961 table->prev->next = table->next;
2381
2/2
✓ Branch 0 taken 2364 times.
✓ Branch 1 taken 2597 times.
4961 if (table->prev->next) table->next->prev = table->prev;
2382 } else {
2383 /* removing the item from the list */
2384
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139936 times.
139936 assert(table == thd->temporary_tables);
2385 /*
2386 slave must reset its temporary list pointer to zero to exclude
2387 passing non-zero value to end_slave via rli->save_temporary_tables
2388 when no temp tables opened, see an invariant below.
2389 */
2390 139936 thd->temporary_tables = table->next;
2391
2/2
✓ Branch 0 taken 794 times.
✓ Branch 1 taken 139142 times.
139936 if (thd->temporary_tables) table->next->prev = nullptr;
2392 }
2393
2/2
✓ Branch 0 taken 2735 times.
✓ Branch 1 taken 142162 times.
144897 if (thd->slave_thread) {
2394 /* natural invariant of temporary_tables */
2395
2/6
✓ Branch 0 taken 2735 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2735 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2735 assert(thd->rli_slave->get_c_rli()->atomic_channel_open_temp_tables ||
2396 !thd->temporary_tables);
2397 2735 --atomic_replica_open_temp_tables;
2398
1/2
✓ Branch 0 taken 2735 times.
✗ Branch 1 not taken.
2735 --thd->rli_slave->get_c_rli()->atomic_channel_open_temp_tables;
2399 }
2400
1/2
✓ Branch 0 taken 144897 times.
✗ Branch 1 not taken.
144897 close_temporary(thd, table, free_share, delete_table);
2401
2402
1/2
✓ Branch 0 taken 144897 times.
✗ Branch 1 not taken.
144897 mysql_mutex_unlock(&thd->LOCK_temporary_tables);
2403
2404 144897 }
2405
2406 /*
2407 Close and delete a temporary table
2408
2409 NOTE
2410 This doesn't unlink table from thd->temporary
2411 If this is needed, use close_temporary_table()
2412 */
2413
2414 146251 void close_temporary(THD *thd, TABLE *table, bool free_share,
2415 bool delete_table) {
2416
1/2
✓ Branch 0 taken 146252 times.
✗ Branch 1 not taken.
146251 handlerton *table_type = table->s->db_type();
2417
1/2
✓ Branch 0 taken 146253 times.
✗ Branch 1 not taken.
146252 DBUG_TRACE;
2418
5/8
✓ Branch 0 taken 146253 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 146253 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 146252 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
146253 DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'", table->s->db.str,
2419 table->s->table_name.str));
2420
2421
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 146207 times.
146253 if (unlikely(opt_userstat)) {
2422
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 table->file->update_global_table_stats();
2423
1/2
✓ Branch 0 taken 45 times.
✗ Branch 1 not taken.
45 table->file->update_global_index_stats();
2424 }
2425
2426
1/2
✓ Branch 0 taken 146252 times.
✗ Branch 1 not taken.
146252 free_io_cache(table);
2427
1/2
✓ Branch 0 taken 146253 times.
✗ Branch 1 not taken.
146252 closefrm(table, false);
2428
2/2
✓ Branch 0 taken 52319 times.
✓ Branch 1 taken 93934 times.
146253 if (delete_table) {
2429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52319 times.
52319 assert(thd);
2430 52319 rm_temporary_table(thd, table_type, table->s->path.str,
2431
1/2
✓ Branch 0 taken 52319 times.
✗ Branch 1 not taken.
52319 table->s->tmp_table_def);
2432 }
2433
2434
1/2
✓ Branch 0 taken 146253 times.
✗ Branch 1 not taken.
146253 if (free_share) {
2435
1/2
✓ Branch 0 taken 146253 times.
✗ Branch 1 not taken.
146253 free_table_share(table->s);
2436 146253 destroy(table);
2437
1/2
✓ Branch 0 taken 146253 times.
✗ Branch 1 not taken.
146253 my_free(table);
2438 }
2439 146253 }
2440
2441 /*
2442 Used by ALTER TABLE when the table is a temporary one. It changes something
2443 only if the ALTER contained a RENAME clause (otherwise, table_name is the old
2444 name).
2445 Prepares a table cache key, which is the concatenation of db, table_name and
2446 thd->slave_proxy_id, separated by '\0'.
2447 */
2448
2449 1141 bool rename_temporary_table(THD *thd, TABLE *table, const char *db,
2450 const char *table_name) {
2451 char *key;
2452 size_t key_length;
2453 1141 TABLE_SHARE *share = table->s;
2454
1/2
✓ Branch 0 taken 1141 times.
✗ Branch 1 not taken.
1141 DBUG_TRACE;
2455
2456
2/4
✓ Branch 0 taken 1141 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1141 times.
1141 if (!(key = (char *)share->mem_root.Alloc(MAX_DBKEY_LENGTH)))
2457 return true; /* purecov: inspected */
2458
2459
1/2
✓ Branch 0 taken 1141 times.
✗ Branch 1 not taken.
1141 key_length = create_table_def_key_tmp(thd, db, table_name, key);
2460 1141 share->set_table_cache_key(key, key_length);
2461 /* Also update table name in DD object. Database name is kept reset. */
2462
2/4
✓ Branch 0 taken 1141 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1141 times.
✗ Branch 3 not taken.
1141 share->tmp_table_def->set_name(table_name);
2463 1141 return false;
2464 1141 }
2465
2466 /**
2467 Force all other threads to stop using the table by upgrading
2468 metadata lock on it and remove unused TABLE instances from cache.
2469
2470 @param thd Thread handler
2471 @param table Table to remove from cache
2472 @param function HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
2473 HA_EXTRA_FORCE_REOPEN if table is not be used
2474 HA_EXTRA_PREPARE_FOR_RENAME if table is to be renamed
2475
2476 @note When returning, the table will be unusable for other threads
2477 until metadata lock is downgraded.
2478
2479 @retval false Success.
2480 @retval true Failure (e.g. because thread was killed).
2481 */
2482
2483 91386 bool wait_while_table_is_used(THD *thd, TABLE *table,
2484 enum ha_extra_function function) {
2485
1/2
✓ Branch 0 taken 91386 times.
✗ Branch 1 not taken.
91386 DBUG_TRACE;
2486
5/8
✓ Branch 0 taken 91386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 91386 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 91385 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
91386 DBUG_PRINT("enter", ("table: '%s' share: %p db_stat: %u version: %lu",
2487 table->s->table_name.str, table->s, table->db_stat,
2488 table->s->version()));
2489
2490
3/4
✓ Branch 0 taken 91386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 91360 times.
91386 if (thd->mdl_context.upgrade_shared_lock(table->mdl_ticket, MDL_EXCLUSIVE,
2491 thd->variables.lock_wait_timeout))
2492 26 return true;
2493
2494 91360 tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN, table->s->db.str,
2495
1/2
✓ Branch 0 taken 91360 times.
✗ Branch 1 not taken.
91360 table->s->table_name.str, false);
2496 /* extra() call must come only after all instances above are closed */
2497
1/2
✓ Branch 0 taken 91360 times.
✗ Branch 1 not taken.
91360 (void)table->file->ha_extra(function);
2498 91360 return false;
2499 91386 }
2500
2501 /**
2502 Check that table exists in data-dictionary or in some storage engine.
2503
2504 @param thd Thread context
2505 @param table Table list element
2506 @param[out] exists Out parameter which is set to true if table
2507 exists and to false otherwise.
2508
2509 @note If there is no table in data-dictionary but it exists in one
2510 of engines (e.g. it was created on another node of NDB cluster)
2511 this function will fetch and add proper table description to
2512 the data-dictionary.
2513
2514 @retval true Some error occurred
2515 @retval false No error. 'exists' out parameter set accordingly.
2516 */
2517
2518 2165019 static bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists) {
2519
1/2
✓ Branch 0 taken 2165075 times.
✗ Branch 1 not taken.
2165019 DBUG_TRACE;
2520
2521 2165075 *exists = true;
2522
2523
2/4
✓ Branch 0 taken 2165064 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2165064 times.
2165075 assert(thd->mdl_context.owns_equal_or_stronger_lock(
2524 MDL_key::TABLE, table->db, table->table_name, MDL_SHARED));
2525
2526
3/4
✓ Branch 0 taken 2165046 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2165045 times.
2165064 if (dd::table_exists(thd->dd_client(), table->db, table->table_name, exists))
2527 1 return true; // Error is already reported.
2528
2529
2/2
✓ Branch 0 taken 1535878 times.
✓ Branch 1 taken 629167 times.
2165045 if (*exists) goto end;
2530
2531 /* Table doesn't exist. Check if some engine can provide it. */
2532
2/4
✓ Branch 0 taken 629188 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 629188 times.
629167 if (ha_check_if_table_exists(thd, table->db, table->table_name, exists)) {
2533 my_printf_error(ER_OUT_OF_RESOURCES,
2534 "Failed to open '%-.64s', error while "
2535 "unpacking from engine",
2536 MYF(0), table->table_name);
2537 return true;
2538 }
2539 629188 end:
2540 2165066 return false;
2541 2165067 }
2542
2543 /**
2544 An error handler which converts, if possible, ER_LOCK_DEADLOCK error
2545 that can occur when we are trying to acquire a metadata lock to
2546 a request for back-off and re-start of open_tables() process.
2547 */
2548
2549 class MDL_deadlock_handler : public Internal_error_handler {
2550 public:
2551 144213186 MDL_deadlock_handler(Open_table_context *ot_ctx_arg)
2552 144213186 : m_ot_ctx(ot_ctx_arg), m_is_active(false) {}
2553
2554 203 bool handle_condition(THD *, uint sql_errno, const char *,
2555 Sql_condition::enum_severity_level *,
2556 const char *) override {
2557
4/4
✓ Branch 0 taken 184 times.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 155 times.
203 if (!m_is_active && sql_errno == ER_LOCK_DEADLOCK) {
2558 /* Disable the handler to avoid infinite recursion. */
2559 29 m_is_active = true;
2560 29 (void)m_ot_ctx->request_backoff_action(
2561 Open_table_context::OT_BACKOFF_AND_RETRY, nullptr);
2562 29 m_is_active = false;
2563 /*
2564 If the above back-off request failed, a new instance of
2565 ER_LOCK_DEADLOCK error was emitted. Thus the current
2566 instance of error condition can be treated as handled.
2567 */
2568 29 return true;
2569 }
2570 174 return false;
2571 }
2572
2573 private:
2574 /** Open table context to be used for back-off request. */
2575 Open_table_context *m_ot_ctx;
2576 /**
2577 Indicates that we are already in the process of handling
2578 ER_LOCK_DEADLOCK error. Allows to re-emit the error from
2579 the error handler without falling into infinite recursion.
2580 */
2581 bool m_is_active;
2582 };
2583
2584 /**
2585 Try to acquire an MDL lock for a table being opened.
2586
2587 @param[in,out] thd Session context, to report errors.
2588 @param[out] ot_ctx Open table context, to hold the back off
2589 state. If we failed to acquire a lock
2590 due to a lock conflict, we add the
2591 failed request to the open table context.
2592 @param[in,out] table_list Table list element for the table being opened.
2593 Its "mdl_request" member specifies the MDL lock
2594 to be requested. If we managed to acquire a
2595 ticket (no errors or lock conflicts occurred),
2596 TABLE_LIST::mdl_request contains a reference
2597 to it on return. However, is not modified if
2598 MDL lock type- modifying flags were provided.
2599 We also use TABLE_LIST::lock_type member to
2600 detect cases when MDL_SHARED_WRITE_LOW_PRIO
2601 lock should be acquired instead of the normal
2602 MDL_SHARED_WRITE lock.
2603 @param[in] flags flags MYSQL_OPEN_FORCE_SHARED_MDL,
2604 MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL or
2605 MYSQL_OPEN_FAIL_ON_MDL_CONFLICT
2606 @sa open_table().
2607 @param[out] mdl_ticket Only modified if there was no error.
2608 If we managed to acquire an MDL
2609 lock, contains a reference to the
2610 ticket, otherwise is set to NULL.
2611
2612 @retval true An error occurred.
2613 @retval false No error, but perhaps a lock conflict, check mdl_ticket.
2614 */
2615
2616 118150854 static bool open_table_get_mdl_lock(THD *thd, Open_table_context *ot_ctx,
2617 TABLE_LIST *table_list, uint flags,
2618 MDL_ticket **mdl_ticket) {
2619 118150854 MDL_request *mdl_request = &table_list->mdl_request;
2620 118150854 MDL_request new_mdl_request;
2621
2622
2/2
✓ Branch 0 taken 122237 times.
✓ Branch 1 taken 118028617 times.
118150854 if (flags &
2623 (MYSQL_OPEN_FORCE_SHARED_MDL | MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL)) {
2624 /*
2625 MYSQL_OPEN_FORCE_SHARED_MDL flag means that we are executing
2626 PREPARE for a prepared statement and want to override
2627 the type-of-operation aware metadata lock which was set
2628 in the parser/during view opening with a simple shared
2629 metadata lock.
2630 This is necessary to allow concurrent execution of PREPARE
2631 and LOCK TABLES WRITE statement against the same table.
2632
2633 MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL flag means that we open
2634 the table in order to get information about it for one of I_S
2635 queries and also want to override the type-of-operation aware
2636 shared metadata lock which was set earlier (e.g. during view
2637 opening) with a high-priority shared metadata lock.
2638 This is necessary to avoid unnecessary waiting and extra
2639 ER_WARN_I_S_SKIPPED_TABLE warnings when accessing I_S tables.
2640
2641 These two flags are mutually exclusive.
2642 */
2643
3/4
✓ Branch 0 taken 47284 times.
✓ Branch 1 taken 74953 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 47284 times.
122237 assert(!(flags & MYSQL_OPEN_FORCE_SHARED_MDL) ||
2644 !(flags & MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL));
2645
2646
3/4
✓ Branch 0 taken 47284 times.
✓ Branch 1 taken 74953 times.
✓ Branch 2 taken 122238 times.
✗ Branch 3 not taken.
122237 MDL_REQUEST_INIT_BY_KEY(&new_mdl_request, &mdl_request->key,
2647 (flags & MYSQL_OPEN_FORCE_SHARED_MDL)
2648 ? MDL_SHARED
2649 : MDL_SHARED_HIGH_PRIO,
2650 MDL_TRANSACTION);
2651 122238 mdl_request = &new_mdl_request;
2652 236059769 } else if (thd->variables.low_priority_updates &&
2653
6/6
✓ Branch 0 taken 2427 times.
✓ Branch 1 taken 118026190 times.
✓ Branch 2 taken 682 times.
✓ Branch 3 taken 1745 times.
✓ Branch 4 taken 193 times.
✓ Branch 5 taken 118028532 times.
118029407 mdl_request->type == MDL_SHARED_WRITE &&
2654
2/2
✓ Branch 0 taken 622 times.
✓ Branch 1 taken 60 times.
682 (table_list->lock_descriptor().type == TL_WRITE_DEFAULT ||
2655
2/2
✓ Branch 0 taken 133 times.
✓ Branch 1 taken 532 times.
622 table_list->lock_descriptor().type ==
2656 TL_WRITE_CONCURRENT_DEFAULT)) {
2657 /*
2658 We are in @@low_priority_updates=1 mode and are going to acquire
2659 SW metadata lock on a table which for which neither LOW_PRIORITY nor
2660 HIGH_PRIORITY clauses were used explicitly.
2661 To keep compatibility with THR_LOCK locks and to avoid starving out
2662 concurrent LOCK TABLES READ statements, we need to acquire the low-prio
2663 version of SW lock instead of a normal SW lock in this case.
2664 */
2665
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 MDL_REQUEST_INIT_BY_KEY(&new_mdl_request, &mdl_request->key,
2666 MDL_SHARED_WRITE_LOW_PRIO, MDL_TRANSACTION);
2667 193 mdl_request = &new_mdl_request;
2668 }
2669
2670
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 118150963 times.
118150963 if (flags & MYSQL_OPEN_FAIL_ON_MDL_CONFLICT) {
2671 /*
2672 When table is being open in order to get data for I_S table,
2673 we might have some tables not only open but also locked (e.g. when
2674 this happens under LOCK TABLES or in a stored function).
2675 As a result by waiting on a conflicting metadata lock to go away
2676 we may create a deadlock which won't entirely belong to the
2677 MDL subsystem and thus won't be detectable by this subsystem's
2678 deadlock detector.
2679 To avoid such situation we skip the trouble-making table if
2680 there is a conflicting lock.
2681 */
2682 if (thd->mdl_context.try_acquire_lock(mdl_request)) return true;
2683 if (mdl_request->ticket == nullptr) {
2684 my_error(ER_WARN_I_S_SKIPPED_TABLE, MYF(0), mdl_request->key.db_name(),
2685 mdl_request->key.name());
2686 return true;
2687 }
2688 } else {
2689 /*
2690 We are doing a normal table open. Let us try to acquire a metadata
2691 lock on the table. If there is a conflicting lock, acquire_lock()
2692 will wait for it to go away. Sometimes this waiting may lead to a
2693 deadlock, with the following results:
2694 1) If a deadlock is entirely within MDL subsystem, it is
2695 detected by the deadlock detector of this subsystem.
2696 ER_LOCK_DEADLOCK error is produced. Then, the error handler
2697 that is installed prior to the call to acquire_lock() attempts
2698 to request a back-off and retry. Upon success, ER_LOCK_DEADLOCK
2699 error is suppressed, otherwise propagated up the calling stack.
2700 2) Otherwise, a deadlock may occur when the wait-for graph
2701 includes edges not visible to the MDL deadlock detector.
2702 One such example is a wait on an InnoDB row lock, e.g. when:
2703 conn C1 gets SR MDL lock on t1 with SELECT * FROM t1
2704 conn C2 gets a row lock on t2 with SELECT * FROM t2 FOR UPDATE
2705 conn C3 gets in and waits on C1 with DROP TABLE t0, t1
2706 conn C2 continues and blocks on C3 with SELECT * FROM t0
2707 conn C1 deadlocks by waiting on C2 by issuing SELECT * FROM
2708 t2 LOCK IN SHARE MODE.
2709 Such circular waits are currently only resolved by timeouts,
2710 e.g. @@innodb_lock_wait_timeout or @@lock_wait_timeout.
2711
2712 Note that we want to force DML deadlock weight for our context
2713 when acquiring locks in this place. This is done to avoid situation
2714 when LOCK TABLES statement, which acquires strong SNRW and SRO locks
2715 on implicitly used tables, deadlocks with a concurrent DDL statement
2716 and the DDL statement is aborted since it is chosen as a deadlock
2717 victim. It is better to choose LOCK TABLES as a victim in this case
2718 as a deadlock can be easily caught here and handled by back-off and retry,
2719 without reporting any error to the user.
2720 We still have a few weird cases, like FLUSH TABLES <table-list> WITH
2721 READ LOCK, where we use "strong" metadata locks and open_tables() is
2722 called with some metadata locks pre-acquired. In these cases we still
2723 want to use DDL deadlock weight as back-off is not possible.
2724 */
2725 118150963 MDL_deadlock_handler mdl_deadlock_handler(ot_ctx);
2726
2727
1/2
✓ Branch 0 taken 118151629 times.
✗ Branch 1 not taken.
118151822 thd->push_internal_handler(&mdl_deadlock_handler);
2728 118151629 thd->mdl_context.set_force_dml_deadlock_weight(ot_ctx->can_back_off());
2729
2730 bool result =
2731
1/2
✓ Branch 0 taken 118152120 times.
✗ Branch 1 not taken.
118151935 thd->mdl_context.acquire_lock(mdl_request, ot_ctx->get_timeout());
2732
2733 118152120 thd->mdl_context.set_force_dml_deadlock_weight(false);
2734
1/2
✓ Branch 0 taken 118151975 times.
✗ Branch 1 not taken.
118152142 thd->pop_internal_handler();
2735
2736
6/6
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 118151815 times.
✓ Branch 2 taken 153 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 153 times.
✓ Branch 5 taken 118151822 times.
118151975 if (result && !ot_ctx->can_recover_from_failed_open()) return true;
2737
2/2
✓ Branch 0 taken 118151935 times.
✓ Branch 1 taken 125 times.
118151975 }
2738 118151935 *mdl_ticket = mdl_request->ticket;
2739 118151935 return false;
2740 }
2741
2742 /**
2743 Check if table's share is being removed from the table definition
2744 cache and, if yes, wait until the flush is complete.
2745
2746 @param thd Thread context.
2747 @param db Database name.
2748 @param table_name Table name.
2749 @param wait_timeout Timeout for waiting.
2750 @param deadlock_weight Weight of this wait for deadlock detector.
2751
2752 @retval false Success. Share is up to date or has been flushed.
2753 @retval true Error (OOM, our was killed, the wait resulted
2754 in a deadlock or timeout). Reported.
2755 */
2756
2757 36 static bool tdc_wait_for_old_version(THD *thd, const char *db,
2758 const char *table_name, ulong wait_timeout,
2759 uint deadlock_weight) {
2760 TABLE_SHARE *share;
2761 36 bool res = false;
2762
2763 36 mysql_mutex_lock(&LOCK_open);
2764
5/6
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 29 times.
43 if ((share = get_cached_table_share(db, table_name)) &&
2765 7 share->has_old_version()) {
2766 struct timespec abstime;
2767
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 set_timespec(&abstime, wait_timeout);
2768
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 res = share->wait_for_old_version(thd, &abstime, deadlock_weight);
2769 }
2770 36 mysql_mutex_unlock(&LOCK_open);
2771 36 return res;
2772 }
2773
2774 /**
2775 Add a dummy LEX object for a view.
2776
2777 @param thd Thread context
2778 @param table_list The list of tables in the view
2779
2780 @retval true error occurred
2781 @retval false view place holder successfully added
2782 */
2783
2784 28 bool add_view_place_holder(THD *thd, TABLE_LIST *table_list) {
2785
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 Prepared_stmt_arena_holder ps_arena_holder(thd);
2786
2/4
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 LEX *lex_obj = new (thd->mem_root) st_lex_local;
2787
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (lex_obj == nullptr) return true;
2788 28 table_list->set_view_query(lex_obj);
2789 // Create empty list of view_tables.
2790 28 table_list->view_tables =
2791
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 new (thd->mem_root) mem_root_deque<TABLE_LIST *>(thd->mem_root);
2792
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (table_list->view_tables == nullptr) return true;
2793 28 return false;
2794 28 }
2795
2796 /**
2797 Open a base table.
2798
2799 @param thd Thread context.
2800 @param table_list Open first table in list.
2801 @param ot_ctx Context with flags which modify how open works
2802 and which is used to recover from a failed
2803 open_table() attempt.
2804 Some examples of flags:
2805 MYSQL_OPEN_IGNORE_FLUSH - Open table even if
2806 someone has done a flush. No version number
2807 checking is done.
2808 MYSQL_OPEN_HAS_MDL_LOCK - instead of acquiring
2809 metadata locks rely on that caller already has
2810 appropriate ones.
2811
2812 Uses a cache of open tables to find a TABLE instance not in use.
2813
2814 If TABLE_LIST::open_strategy is set to OPEN_IF_EXISTS, the table is
2815 opened only if it exists. If the open strategy is OPEN_STUB, the
2816 underlying table is never opened. In both cases, metadata locks are
2817 always taken according to the lock strategy.
2818
2819 @retval true Open failed. "action" parameter may contain type of action
2820 needed to remedy problem before retrying again.
2821 @retval false Success. Members of TABLE_LIST structure are filled properly
2822 (e.g. TABLE_LIST::table is set for real tables and
2823 TABLE_LIST::view is set for views).
2824 */
2825
2826 118827861 bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) {
2827 118827861 TABLE *table = nullptr;
2828 118827861 TABLE_SHARE *share = nullptr;
2829 const char *key;
2830 size_t key_length;
2831 118827861 const char *alias = table_list->alias;
2832 118827861 uint flags = ot_ctx->get_flags();
2833 118828197 MDL_ticket *mdl_ticket = nullptr;
2834 118828197 int error = 0;
2835 118828197 bool backup_protection_acquired = false;
2836
2837
1/2
✓ Branch 0 taken 118829164 times.
✗ Branch 1 not taken.
118828197 DBUG_TRACE;
2838
2839 // Temporary tables and derived tables are not allowed:
2840
4/4
✓ Branch 0 taken 118829168 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 118829168 times.
✓ Branch 3 taken 3 times.
118829164 assert(!is_temporary_table(table_list) && !table_list->is_derived());
2841
2842 /*
2843 The table must not be opened already. The table can be pre-opened for
2844 some statements if it is a temporary table.
2845
2846 open_temporary_table() must be used to open temporary tables.
2847 A derived table cannot be opened with this.
2848 */
2849
3/4
✓ Branch 0 taken 118808483 times.
✓ Branch 1 taken 20656 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 118808483 times.
118829168 assert(table_list->is_view() || table_list->table == nullptr);
2850
2851 /* an open table operation needs a lot of the stack space */
2852
3/4
✓ Branch 0 taken 118828690 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 118828689 times.
118829139 if (check_stack_overrun(thd, STACK_MIN_SIZE_FOR_OPEN, (uchar *)&alias))
2853 1 return true;
2854
2855 // New DD- In current_thd->is_strict_mode() mode we call open_table
2856 // on new DD tables like mysql.tables/* when CREATE fails and we
2857 // try to abort the operation and invoke quick_rm_table().
2858 // Currently, we ignore deleting table in strict mode. Need to fix this.
2859 // TODO.
2860
2861
5/6
✓ Branch 0 taken 118829111 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 118829106 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 3 times.
118828689 DBUG_EXECUTE_IF("kill_query_on_open_table_from_tz_find", {
2862 /*
2863 When on calling my_tz_find the following
2864 tables are opened in specified order: time_zone_name,
2865 time_zone, time_zone_transition_type,
2866 time_zone_transition. Emulate killing a query
2867 on opening the second table in the list.
2868 */
2869 if (!strcmp("time_zone", table_list->table_name))
2870 thd->killed = THD::KILL_QUERY;
2871 });
2872
2873
6/6
✓ Branch 0 taken 23463373 times.
✓ Branch 1 taken 95365765 times.
✓ Branch 2 taken 134 times.
✓ Branch 3 taken 23462897 times.
✓ Branch 4 taken 134 times.
✓ Branch 5 taken 118828662 times.
118829138 if (!(flags & MYSQL_OPEN_IGNORE_KILLED) && thd->killed) return true;
2874
2875 /*
2876 Check if we're trying to take a write lock in a read only transaction.
2877
2878 Note that we allow write locks on log tables as otherwise logging
2879 to general/slow log would be disabled in read only transactions.
2880 */
2881
6/6
✓ Branch 0 taken 33653207 times.
✓ Branch 1 taken 85175026 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 33653178 times.
✓ Branch 4 taken 29 times.
✓ Branch 5 taken 118828204 times.
118828691 if (table_list->mdl_request.is_write_lock_request() && thd->tx_read_only &&
2882
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 !(flags & (MYSQL_LOCK_LOG_TABLE | MYSQL_OPEN_HAS_MDL_LOCK))) {
2883
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 my_error(ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, MYF(0));
2884 29 return true;
2885 }
2886
2887 /*
2888 FLUSH TABLES is ignored for DD, I_S and P_S tables/views.
2889 Hence setting MYSQL_OPEN_IGNORE_FLUSH flag.
2890 */
2891
8/8
✓ Branch 0 taken 118388981 times.
✓ Branch 1 taken 439223 times.
✓ Branch 2 taken 20910780 times.
✓ Branch 3 taken 97478861 times.
✓ Branch 4 taken 755249 times.
✓ Branch 5 taken 20154966 times.
✓ Branch 6 taken 98673353 times.
✓ Branch 7 taken 20154946 times.
139738419 if (table_list->is_system_view || belongs_to_dd_table(table_list) ||
2892 20910780 belongs_to_p_s(table_list))
2893 98673353 flags |= MYSQL_OPEN_IGNORE_FLUSH;
2894
2895
1/2
✓ Branch 0 taken 118829026 times.
✗ Branch 1 not taken.
118828299 key_length = get_table_def_key(table_list, &key);
2896
2897 // If a table in a secondary storage engine has been requested,
2898 // adjust the key to refer to the secondary table.
2899 118829026 std::string secondary_key;
2900
2/2
✓ Branch 0 taken 549 times.
✓ Branch 1 taken 118828278 times.
118828827 if ((flags & MYSQL_OPEN_SECONDARY_ENGINE) != 0) {
2901
1/2
✓ Branch 0 taken 549 times.
✗ Branch 1 not taken.
1098 secondary_key = create_table_def_key_secondary(
2902 549 table_list->get_db_name(), table_list->get_table_name());
2903 549 key = secondary_key.data();
2904 549 key_length = secondary_key.length();
2905 }
2906
2907 /*
2908 If we're in pre-locked or LOCK TABLES mode, let's try to find the
2909 requested table in the list of pre-opened and locked tables. If the
2910 table is not there, return an error - we can't open not pre-opened
2911 tables in pre-locked/LOCK TABLES mode.
2912
2913 There is a special case where we allow opening not pre-opened tables
2914 in LOCK TABLES mode for new DD tables. The reason is as following.
2915 With new DD, IS system views need to be accessible in LOCK TABLE
2916 mode without user explicitly calling LOCK TABLE on IS view or its
2917 underlying DD tables. This is required to keep the old behavior the
2918 MySQL server had without new DD.
2919
2920 In case user executes IS system view under LOCK TABLE mode
2921 (LTM and not prelocking), then MySQL server implicitly opens system
2922 view and related DD tables. Such DD tables are then implicitly closed
2923 upon end of statement execution.
2924
2925 Our goal is to hide DD tables from users, so there is no possibility of
2926 explicit locking DD table using LOCK TABLE. In case user does LOCK TABLE
2927 on IS system view explicitly, MySQL server throws a error.
2928
2929 TODO: move this block into a separate function.
2930 */
2931
6/6
✓ Branch 0 taken 95467 times.
✓ Branch 1 taken 118732555 times.
✓ Branch 2 taken 95135 times.
✓ Branch 3 taken 332 times.
✓ Branch 4 taken 45511 times.
✓ Branch 5 taken 118782511 times.
118923157 if (thd->locked_tables_mode && !(flags & MYSQL_OPEN_GET_NEW_TABLE) &&
2932
2/2
✓ Branch 0 taken 54773 times.
✓ Branch 1 taken 40362 times.
95135 !(in_LTM(thd) &&
2933
4/4
✓ Branch 0 taken 47327 times.
✓ Branch 1 taken 7446 times.
✓ Branch 2 taken 5847 times.
✓ Branch 3 taken 41480 times.
54773 (table_list->is_system_view || belongs_to_dd_table(table_list) ||
2934
2/2
✓ Branch 0 taken 5149 times.
✓ Branch 1 taken 698 times.
5847 belongs_to_p_s(table_list)))) { // Using table locks
2935 45511 TABLE *best_table = nullptr;
2936 45511 int best_distance = INT_MIN;
2937
2/2
✓ Branch 0 taken 247395 times.
✓ Branch 1 taken 45456 times.
292851 for (table = thd->open_tables; table; table = table->next) {
2938
2/2
✓ Branch 0 taken 119983 times.
✓ Branch 1 taken 127412 times.
247395 if (table->s->table_cache_key.length == key_length &&
2939
2/2
✓ Branch 0 taken 50031 times.
✓ Branch 1 taken 69952 times.
119983 !memcmp(table->s->table_cache_key.str, key, key_length)) {
2940
1/2
✓ Branch 0 taken 50031 times.
✗ Branch 1 not taken.
50031 if (!my_strcasecmp(system_charset_info, table->alias, alias) &&
2941
6/6
✓ Branch 0 taken 48802 times.
✓ Branch 1 taken 1229 times.
✓ Branch 2 taken 48730 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 48005 times.
✓ Branch 5 taken 2026 times.
98761 table->query_id != thd->query_id && /* skip tables already used */
2942
2/2
✓ Branch 0 taken 43660 times.
✓ Branch 1 taken 5070 times.
48730 (thd->locked_tables_mode == LTM_LOCK_TABLES ||
2943
2/2
✓ Branch 0 taken 42935 times.
✓ Branch 1 taken 725 times.
43660 table->query_id == 0)) {
2944 48005 int distance = ((int)table->reginfo.lock_type -
2945 48005 (int)table_list->lock_descriptor().type);
2946
2947 /*
2948 Find a table that either has the exact lock type requested,
2949 or has the best suitable lock. In case there is no locked
2950 table that has an equal or higher lock than requested,
2951 we us the closest matching lock to be able to produce an error
2952 message about wrong lock mode on the table. The best_table
2953 is changed if bd < 0 <= d or bd < d < 0 or 0 <= d < bd.
2954
2955 distance < 0 - No suitable lock found
2956 distance > 0 - we have lock mode higher then we require
2957 distance == 0 - we have lock mode exactly which we need
2958 */
2959
5/6
✓ Branch 0 taken 44856 times.
✓ Branch 1 taken 3149 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 44856 times.
✓ Branch 4 taken 3147 times.
✓ Branch 5 taken 2 times.
48005 if ((best_distance < 0 && distance > best_distance) ||
2960
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 3140 times.
3147 (distance >= 0 && distance < best_distance)) {
2961 44863 best_distance = distance;
2962 44863 best_table = table;
2963
2/2
✓ Branch 0 taken 55 times.
✓ Branch 1 taken 44808 times.
44863 if (best_distance == 0) {
2964 /*
2965 We have found a perfect match and can finish iterating
2966 through open tables list. Check for table use conflict
2967 between calling statement and SP/trigger is done in
2968 lock_tables().
2969 */
2970 55 break;
2971 }
2972 }
2973 }
2974 }
2975 }
2976
2/2
✓ Branch 0 taken 44852 times.
✓ Branch 1 taken 659 times.
45511 if (best_table) {
2977 44852 table = best_table;
2978 44852 table->query_id = thd->query_id;
2979
3/8
✓ Branch 0 taken 44852 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44852 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 44852 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
44852 DBUG_PRINT("info", ("Using locked table"));
2980 44852 goto reset;
2981 }
2982 /*
2983 Is this table a view and not a base table?
2984 (it is work around to allow to open view with locked tables,
2985 real fix will be made after definition cache will be made)
2986
2987 Since opening of view which was not explicitly locked by LOCK
2988 TABLES breaks metadata locking protocol (potentially can lead
2989 to deadlocks) it should be disallowed.
2990 */
2991
3/4
✓ Branch 0 taken 659 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 598 times.
✓ Branch 3 taken 61 times.
659 if (thd->mdl_context.owns_equal_or_stronger_lock(
2992 MDL_key::TABLE, table_list->db, table_list->table_name,
2993 MDL_SHARED)) {
2994 /*
2995 Note that we can't be 100% sure that it is a view since it's
2996 possible that we either simply have not found unused TABLE
2997 instance in THD::open_tables list or were unable to open table
2998 during prelocking process (in this case in theory we still
2999 should hold shared metadata lock on it).
3000 */
3001
1/2
✓ Branch 0 taken 598 times.
✗ Branch 1 not taken.
598 dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client());
3002 598 const dd::View *view = nullptr;
3003
4/10
✓ Branch 0 taken 598 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 598 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 530 times.
✓ Branch 5 taken 68 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
1196 if (!thd->dd_client()->acquire(table_list->db, table_list->table_name,
3004
4/8
✓ Branch 0 taken 598 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 598 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 598 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 598 times.
✗ Branch 7 not taken.
1794 &view) &&
3005
2/2
✓ Branch 0 taken 530 times.
✓ Branch 1 taken 68 times.
598 view != nullptr) {
3006 /*
3007 If parent_l of the table_list is non null then a merge table
3008 has this view as child table, which is not supported.
3009 */
3010
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 529 times.
530 if (table_list->parent_l) {
3011
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_WRONG_MRG_TABLE, MYF(0));
3012 1 return true;
3013 }
3014
3015 /*
3016 In the case of a CREATE, add a dummy LEX object to
3017 indicate the presence of a view amd skip processing the
3018 existing view.
3019 */
3020
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 529 times.
529 if (table_list->open_strategy == TABLE_LIST::OPEN_FOR_CREATE)
3021 return add_view_place_holder(thd, table_list);
3022
3023
3/4
✓ Branch 0 taken 529 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 522 times.
✓ Branch 3 taken 7 times.
529 if (!tdc_open_view(thd, table_list, key, key_length)) {
3024
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 522 times.
522 assert(table_list->is_view());
3025 522 return false; // VIEW
3026 }
3027 }
3028
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 523 times.
598 }
3029 /*
3030 No table in the locked tables list. In case of explicit LOCK TABLES
3031 this can happen if a user did not include the table into the list.
3032 In case of pre-locked mode locked tables list is generated automatically,
3033 so we may only end up here if the table did not exist when
3034 locked tables list was created.
3035 */
3036
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 101 times.
136 if (thd->locked_tables_mode == LTM_PRELOCKED)
3037
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
3038 else
3039
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
3040 136 return true;
3041 }
3042
3043 // Non pre-locked/LOCK TABLES mode, and not using secondary storage engine.
3044 // This is the normal use case.
3045
3046
2/2
✓ Branch 0 taken 118150881 times.
✓ Branch 1 taken 631630 times.
118782511 if ((flags & (MYSQL_OPEN_HAS_MDL_LOCK | MYSQL_OPEN_SECONDARY_ENGINE)) == 0) {
3047 /*
3048 We are not under LOCK TABLES and going to acquire write-lock/
3049 modify the base table. We need to acquire protection against
3050 global read lock until end of this statement in order to have
3051 this statement blocked by active FLUSH TABLES WITH READ LOCK.
3052
3053 We don't block acquire this protection under LOCK TABLES as
3054 such protection already acquired at LOCK TABLES time and
3055 not released until UNLOCK TABLES.
3056
3057 We don't block statements which modify only temporary tables
3058 as these tables are not preserved by backup by any form of
3059 backup which uses FLUSH TABLES WITH READ LOCK.
3060
3061 TODO: The fact that we sometimes acquire protection against
3062 GRL only when we encounter table to be write-locked
3063 slightly increases probability of deadlock.
3064 This problem will be solved once Alik pushes his
3065 temporary table refactoring patch and we can start
3066 pre-acquiring metadata locks at the beginning of
3067 open_tables() call.
3068 */
3069 118150881 if (table_list->mdl_request.is_write_lock_request() &&
3070
2/2
✓ Branch 0 taken 32159884 times.
✓ Branch 1 taken 1037785 times.
33197669 !(flags &
3071 (MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK | MYSQL_OPEN_FORCE_SHARED_MDL |
3072 MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL |
3073
4/4
✓ Branch 0 taken 33197669 times.
✓ Branch 1 taken 84954166 times.
✓ Branch 2 taken 20760174 times.
✓ Branch 3 taken 97391616 times.
151349459 MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK)) &&
3074
2/2
✓ Branch 0 taken 20760073 times.
✓ Branch 1 taken 11399766 times.
32159884 !ot_ctx->has_protection_against_grl()) {
3075 20760174 MDL_request protection_request;
3076 20760174 MDL_deadlock_handler mdl_deadlock_handler(ot_ctx);
3077
3078
3/4
✓ Branch 0 taken 20759786 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 20759766 times.
20760039 if (thd->global_read_lock.can_acquire_protection()) return true;
3079
3080
1/2
✓ Branch 0 taken 20760320 times.
✗ Branch 1 not taken.
20759766 MDL_REQUEST_INIT(&protection_request, MDL_key::GLOBAL, "", "",
3081 MDL_INTENTION_EXCLUSIVE, MDL_STATEMENT);
3082
3083 /*
3084 Install error handler which if possible will convert deadlock error
3085 into request to back-off and restart process of opening tables.
3086
3087 Prefer this context as a victim in a deadlock when such a deadlock
3088 can be easily handled by back-off and retry.
3089 */
3090
1/2
✓ Branch 0 taken 20760284 times.
✗ Branch 1 not taken.
20760320 thd->push_internal_handler(&mdl_deadlock_handler);
3091 20760284 thd->mdl_context.set_force_dml_deadlock_weight(ot_ctx->can_back_off());
3092
3093
1/2
✓ Branch 0 taken 20759679 times.
✗ Branch 1 not taken.
20760161 bool result = thd->mdl_context.acquire_lock(&protection_request,
3094 ot_ctx->get_timeout());
3095
3096 /*
3097 Unlike in other places where we acquire protection against global read
3098 lock, the read_only state is not checked here since we check its state
3099 later in mysql_lock_tables()
3100 */
3101
3102 20759679 thd->mdl_context.set_force_dml_deadlock_weight(false);
3103
1/2
✓ Branch 0 taken 20759842 times.
✗ Branch 1 not taken.
20760022 thd->pop_internal_handler();
3104
3105
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 20759823 times.
20759842 if (result) return true;
3106
3107 20759823 ot_ctx->set_has_protection_against_grl();
3108
2/2
✓ Branch 0 taken 20760176 times.
✓ Branch 1 taken 9 times.
20759913 }
3109
3110
5/6
✓ Branch 0 taken 118151767 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 118151718 times.
✓ Branch 3 taken 49 times.
✓ Branch 4 taken 160 times.
✓ Branch 5 taken 118151607 times.
236303510 if (open_table_get_mdl_lock(thd, ot_ctx, table_list, flags, &mdl_ticket) ||
3111
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 118151693 times.
118151718 mdl_ticket == nullptr) {
3112
2/4
✓ Branch 0 taken 160 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 160 times.
✗ Branch 3 not taken.
160 DEBUG_SYNC(thd, "before_open_table_wait_refresh");
3113 160 return true;
3114 }
3115
3/4
✓ Branch 0 taken 107602372 times.
✓ Branch 1 taken 10549119 times.
✓ Branch 2 taken 107602946 times.
✗ Branch 3 not taken.
118151607 DEBUG_SYNC(thd, "after_open_table_mdl_shared");
3116 } else {
3117 /*
3118 Grab reference to the MDL lock ticket that was acquired
3119 by the caller.
3120 */
3121 631630 mdl_ticket = table_list->mdl_request.ticket;
3122 }
3123
3124
2/2
✓ Branch 0 taken 117267523 times.
✓ Branch 1 taken 1516172 times.
118783695 if (table_list->open_strategy == TABLE_LIST::OPEN_IF_EXISTS ||
3125
2/2
✓ Branch 0 taken 649933 times.
✓ Branch 1 taken 116617590 times.
117267523 table_list->open_strategy == TABLE_LIST::OPEN_FOR_CREATE) {
3126 bool exists;
3127
3128
3/4
✓ Branch 0 taken 2165066 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2165065 times.
2795291 if (check_if_table_exists(thd, table_list, &exists)) return true;
3129
3130 /*
3131 If the table does not exist then upgrade the lock to the EXCLUSIVE MDL
3132 lock.
3133 */
3134
2/2
✓ Branch 0 taken 629189 times.
✓ Branch 1 taken 1535876 times.
2165065 if (!exists) {
3135
2/2
✓ Branch 0 taken 629146 times.
✓ Branch 1 taken 43 times.
629189 if (table_list->open_strategy == TABLE_LIST::OPEN_FOR_CREATE &&
3136
2/2
✓ Branch 0 taken 613811 times.
✓ Branch 1 taken 15335 times.
629146 !(flags & (MYSQL_OPEN_FORCE_SHARED_MDL |
3137 MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL))) {
3138 613811 MDL_deadlock_handler mdl_deadlock_handler(ot_ctx);
3139
3140
1/2
✓ Branch 0 taken 613811 times.
✗ Branch 1 not taken.
613810 thd->push_internal_handler(&mdl_deadlock_handler);
3141
3142
3/4
✓ Branch 0 taken 550290 times.
✓ Branch 1 taken 63521 times.
✓ Branch 2 taken 550290 times.
✗ Branch 3 not taken.
613811 DEBUG_SYNC(thd, "before_upgrading_lock_from_S_to_X_for_create_table");
3143
1/2
✓ Branch 0 taken 613807 times.
✗ Branch 1 not taken.
613811 bool wait_result = thd->mdl_context.upgrade_shared_lock(
3144 table_list->mdl_request.ticket, MDL_EXCLUSIVE,
3145 thd->variables.lock_wait_timeout);
3146
3147
1/2
✓ Branch 0 taken 613807 times.
✗ Branch 1 not taken.
613807 thd->pop_internal_handler();
3148
3/4
✓ Branch 0 taken 550287 times.
✓ Branch 1 taken 63521 times.
✓ Branch 2 taken 550289 times.
✗ Branch 3 not taken.
613807 DEBUG_SYNC(thd, "after_upgrading_lock_from_S_to_X_for_create_table");
3149
3150 /* Deadlock or timeout occurred while upgrading the lock. */
3151
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 613807 times.
613810 if (wait_result) return true;
3152
2/2
✓ Branch 0 taken 613805 times.
✓ Branch 1 taken 3 times.
613810 }
3153
3154 629183 return false;
3155 }
3156
3157 /* Table exists. Let us try to open it. */
3158
2/2
✓ Branch 0 taken 76889 times.
✓ Branch 1 taken 116540701 times.
118153466 } else if (table_list->open_strategy == TABLE_LIST::OPEN_STUB)
3159 76889 return false;
3160
3161 118076577 retry_share : {
3162 118076611 Table_cache *tc = table_cache_manager.get_cache(thd);
3163
3164
1/2
✓ Branch 0 taken 118076807 times.
✗ Branch 1 not taken.
118077071 tc->lock();
3165
3166 /*
3167 Try to get unused TABLE object or at least pointer to
3168 TABLE_SHARE from the table cache.
3169 */
3170
2/2
✓ Branch 0 taken 118056266 times.
✓ Branch 1 taken 20734 times.
118076807 if (!table_list->is_view())
3171
1/2
✓ Branch 0 taken 118056119 times.
✗ Branch 1 not taken.
118056266 table = tc->get_table(thd, key, key_length, &share);
3172
3173
2/2
✓ Branch 0 taken 112869325 times.
✓ Branch 1 taken 5207528 times.
118076853 if (table) {
3174 /* We have found an unused TABLE object. */
3175
3176
2/2
✓ Branch 0 taken 16066147 times.
✓ Branch 1 taken 96803178 times.
112869325 if (!(flags & MYSQL_OPEN_IGNORE_FLUSH)) {
3177 /*
3178 TABLE_SHARE::version can only be initialised while holding the
3179 LOCK_open and in this case no one has a reference to the share
3180 object, if a reference exists to the share object it is necessary
3181 to lock both LOCK_open AND all table caches in order to update
3182 TABLE_SHARE::version. The same locks are required to increment
3183 refresh_version global variable.
3184
3185 As result it is safe to compare TABLE_SHARE::version and
3186 refresh_version values while having only lock on the table
3187 cache for this thread.
3188
3189 Table cache should not contain any unused TABLE objects with
3190 old versions.
3191 */
3192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16066179 times.
16066147 assert(!share->has_old_version());
3193
3194 /*
3195 Still some of already opened might become outdated (e.g. due to
3196 concurrent table flush). So we need to compare version of opened
3197 tables with version of TABLE object we just have got.
3198 */
3199
4/6
✓ Branch 0 taken 463658 times.
✓ Branch 1 taken 15602521 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 463591 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 16066112 times.
16529770 if (thd->open_tables &&
3200 463658 thd->open_tables->s->version() != share->version()) {
3201 tc->release_table(thd, table);
3202 tc->unlock();
3203 (void)ot_ctx->request_backoff_action(
3204 Open_table_context::OT_REOPEN_TABLES, nullptr);
3205 return true;
3206 }
3207 }
3208
1/2
✓ Branch 0 taken 112869538 times.
✗ Branch 1 not taken.
112869290 tc->unlock();
3209
3210 /* Call rebind_psi outside of the critical section. */
3211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 112869538 times.
112869538 assert(table->file != nullptr);
3212
1/2
✓ Branch 0 taken 112869438 times.
✗ Branch 1 not taken.
112869538 table->file->rebind_psi();
3213
1/2
✓ Branch 0 taken 112869629 times.
✗ Branch 1 not taken.
112869438 table->file->ha_extra(HA_EXTRA_RESET_STATE);
3214
3215 112869629 thd->status_var.table_open_cache_hits++;
3216 112869629 goto table_found;
3217
2/2
✓ Branch 0 taken 500211 times.
✓ Branch 1 taken 4707317 times.
5207528 } else if (share) {
3218 /*
3219 We weren't able to get an unused TABLE object. Still we have
3220 found TABLE_SHARE for it. So let us try to create new TABLE
3221 for it. We start by incrementing share's reference count and
3222 checking its version.
3223 */
3224
1/2
✓ Branch 0 taken 500211 times.
✗ Branch 1 not taken.
500211 mysql_mutex_lock(&LOCK_open);
3225
1/2
✓ Branch 0 taken 500211 times.
✗ Branch 1 not taken.
500211 tc->unlock();
3226
1/2
✓ Branch 0 taken 500211 times.
✗ Branch 1 not taken.
500211 share->increment_ref_count();
3227 500211 goto share_found;
3228 } else {
3229 /*
3230 We have not found neither TABLE nor TABLE_SHARE object in
3231 table cache (this means that there are no TABLE objects for
3232 it in it).
3233 Let us try to get TABLE_SHARE from table definition cache or
3234 from disk and then to create TABLE object for it.
3235 */
3236
1/2
✓ Branch 0 taken 4707334 times.
✗ Branch 1 not taken.
4707317 tc->unlock();
3237 }
3238 }
3239
3240
1/2
✓ Branch 0 taken 4707336 times.
✗ Branch 1 not taken.
4707334 mysql_mutex_lock(&LOCK_open);
3241
3242
2/2
✓ Branch 0 taken 9231 times.
✓ Branch 1 taken 4698100 times.
4707331 if (!(share = get_table_share_with_discover(
3243 thd, table_list, key, key_length,
3244
1/2
✓ Branch 0 taken 4707331 times.
✗ Branch 1 not taken.
4707336 flags & MYSQL_OPEN_SECONDARY_ENGINE, &error))) {
3245
1/2
✓ Branch 0 taken 9231 times.
✗ Branch 1 not taken.
9231 mysql_mutex_unlock(&LOCK_open);
3246 /*
3247 If thd->is_error() is not set, we either need discover
3248 (error == 7), or the error was silenced by the prelocking
3249 handler (error == 0), in which case we should skip this
3250 table.
3251 */
3252
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 9231 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 9231 times.
9231 if (error == 7 && !thd->is_error()) {
3253 (void)ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER,
3254 table_list);
3255 }
3256 9231 return true;
3257 }
3258
3259 /*
3260 If a view is anticipated or the TABLE_SHARE object is a view, perform
3261 a version check for it without creating a TABLE object.
3262
3263 Note that there is no need to call TABLE_SHARE::has_old_version() as we
3264 do for regular tables, because view shares are always up to date.
3265 */
3266
6/6
✓ Branch 0 taken 4677492 times.
✓ Branch 1 taken 20608 times.
✓ Branch 2 taken 564931 times.
✓ Branch 3 taken 4112561 times.
✓ Branch 4 taken 585539 times.
✓ Branch 5 taken 4112561 times.
4698100 if (table_list->is_view() || share->is_view) {
3267 585539 bool view_open_result = true;
3268 /*
3269 If parent_l of the table_list is non null then a merge table
3270 has this view as child table, which is not supported.
3271 */
3272
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 585539 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
585539 if (table_list->parent_l) my_error(ER_WRONG_MRG_TABLE, MYF(0));
3273 /*
3274 Validate metadata version: in particular, that a view is opened when
3275 it is expected, or that a table is opened when it is expected.
3276 */
3277
3/4
✓ Branch 0 taken 585539 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 585521 times.
✓ Branch 3 taken 18 times.
585539 else if (check_and_update_table_version(thd, table_list, share))
3278 ;
3279
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 585491 times.
585521 else if (table_list->open_strategy == TABLE_LIST::OPEN_FOR_CREATE) {
3280 /*
3281 Skip reading the view definition if the open is for a table to be
3282 created. This scenario will happen only when there exists a view and
3283 the current CREATE TABLE request is with the same name.
3284 */
3285
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 release_table_share(share);
3286
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 mysql_mutex_unlock(&LOCK_open);
3287
3288 /*
3289 The LEX object is used by the executor and other parts of the
3290 code to detect the presence of a view. As this is
3291 OPEN_FOR_CREATE we skip the call to open_and_read_view(),
3292 which creates the LEX object, and create a dummy LEX object.
3293
3294 For SP and PS, LEX objects are created at the time of
3295 statement prepare and open_table() is called for every execute
3296 after that. Skip creation of LEX objects if it is already
3297 present.
3298 */
3299
3/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
30 if (!table_list->is_view()) return add_view_place_holder(thd, table_list);
3300 2 return false;
3301 } else {
3302 /*
3303 Read definition of existing view.
3304 */
3305
1/2
✓ Branch 0 taken 585491 times.
✗ Branch 1 not taken.
585491 view_open_result = open_and_read_view(thd, share, table_list);
3306 }
3307
3308 /* TODO: Don't free this */
3309
1/2
✓ Branch 0 taken 585509 times.
✗ Branch 1 not taken.
585509 release_table_share(share);
3310
1/2
✓ Branch 0 taken 585508 times.
✗ Branch 1 not taken.
585509 mysql_mutex_unlock(&LOCK_open);
3311
3312
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 585446 times.
585508 if (view_open_result) return true;
3313
3314
3/4
✓ Branch 0 taken 585447 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 585424 times.
585446 if (parse_view_definition(thd, table_list)) return true;
3315
3316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 585424 times.
585424 assert(table_list->is_view());
3317
3318 585424 return false;
3319 }
3320
3321 4112561 share_found:
3322
2/2
✓ Branch 0 taken 1152022 times.
✓ Branch 1 taken 3460750 times.
4612772 if (!(flags & MYSQL_OPEN_IGNORE_FLUSH)) {
3323
2/2
✓ Branch 0 taken 36 times.
✓ Branch 1 taken 1151986 times.
1152022 if (share->has_old_version()) {
3324 /*
3325 We already have an MDL lock. But we have encountered an old
3326 version of table in the table definition cache which is possible
3327 when someone changes the table version directly in the cache
3328 without acquiring a metadata lock (e.g. this can happen during
3329 "rolling" FLUSH TABLE(S)).
3330 Release our reference to share, wait until old version of
3331 share goes away and then try to get new version of table share.
3332 */
3333
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 release_table_share(share);
3334
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 mysql_mutex_unlock(&LOCK_open);
3335
3336 36 MDL_deadlock_handler mdl_deadlock_handler(ot_ctx);
3337 bool wait_result;
3338
3339
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 thd->push_internal_handler(&mdl_deadlock_handler);
3340
3341 /*
3342 In case of deadlock we would like this thread to be preferred as
3343 a deadlock victim when this deadlock can be nicely handled by
3344 back-off and retry. We still have a few weird cases, like
3345 FLUSH TABLES <table-list> WITH READ LOCK, where we use strong
3346 metadata locks and open_tables() is called with some metadata
3347 locks pre-acquired. In these cases we still want to use DDL
3348 deadlock weight.
3349 */
3350 36 uint deadlock_weight = ot_ctx->can_back_off()
3351
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 16 times.
36 ? MDL_wait_for_subgraph::DEADLOCK_WEIGHT_DML
3352
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 : mdl_ticket->get_deadlock_weight();
3353
3354 wait_result =
3355
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 tdc_wait_for_old_version(thd, table_list->db, table_list->table_name,
3356 ot_ctx->get_timeout(), deadlock_weight);
3357
3358
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 thd->pop_internal_handler();
3359
3360
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 34 times.
36 if (wait_result) return true;
3361
3362
2/4
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
✗ Branch 3 not taken.
34 DEBUG_SYNC(thd, "open_table_before_retry");
3363 34 goto retry_share;
3364
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 34 times.
36 }
3365
3366
4/6
✓ Branch 0 taken 192670 times.
✓ Branch 1 taken 959316 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 192670 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1151986 times.
1344656 if (thd->open_tables &&
3367 192670 thd->open_tables->s->version() != share->version()) {
3368 /*
3369 If the version changes while we're opening the tables,
3370 we have to back off, close all the tables opened-so-far,
3371 and try to reopen them. Note: refresh_version is currently
3372 changed only during FLUSH TABLES.
3373 */
3374 release_table_share(share);
3375 mysql_mutex_unlock(&LOCK_open);
3376 (void)ot_ctx->request_backoff_action(Open_table_context::OT_REOPEN_TABLES,
3377 nullptr);
3378 return true;
3379 }
3380 }
3381
3382
1/2
✓ Branch 0 taken 4612736 times.
✗ Branch 1 not taken.
4612736 mysql_mutex_unlock(&LOCK_open);
3383
3384
3/4
✓ Branch 0 taken 4502859 times.
✓ Branch 1 taken 109877 times.
✓ Branch 2 taken 4502859 times.
✗ Branch 3 not taken.
4612736 DEBUG_SYNC(thd, "open_table_found_share");
3385
3386 9797834 if (table_list->mdl_request.type >= MDL_SHARED_WRITE &&
3387
2/2
✓ Branch 0 taken 533801 times.
✓ Branch 1 taken 38561 times.
572362 !(flags & (MYSQL_LOCK_LOG_TABLE | MYSQL_OPEN_HAS_MDL_LOCK)) &&
3388
6/8
✓ Branch 0 taken 572362 times.
✓ Branch 1 taken 4040374 times.
✓ Branch 2 taken 533801 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 533801 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 21987 times.
✓ Branch 7 taken 4590749 times.
5718899 share->db_type() &&
3389
3/4
✓ Branch 0 taken 533801 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21987 times.
✓ Branch 3 taken 511814 times.
533801 !(share->db_type()->flags & HTON_SUPPORTS_ONLINE_BACKUPS)) {
3390
3/4
✓ Branch 0 taken 21987 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 21970 times.
43974 if (thd->backup_tables_lock.abort_if_acquired() ||
3391
3/4
✓ Branch 0 taken 21987 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 21970 times.
21987 thd->backup_tables_lock.acquire_protection(thd, MDL_STATEMENT,
3392 ot_ctx->get_timeout()))
3393 17 goto err_lock;
3394
3395 21970 backup_protection_acquired = true;
3396 }
3397
3398 {
3399
1/2
✓ Branch 0 taken 4612724 times.
✗ Branch 1 not taken.
4612719 dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client());
3400 4612724 const dd::Table *table_def = nullptr;
3401
2/2
✓ Branch 0 taken 4433120 times.
✓ Branch 1 taken 179604 times.
9045834 if (!(flags & MYSQL_OPEN_NO_NEW_TABLE_IN_SE) &&
3402
9/18
✓ Branch 0 taken 4433119 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4433120 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4433110 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4433110 times.
✓ Branch 8 taken 4433116 times.
✓ Branch 9 taken 179598 times.
✓ Branch 10 taken 4433115 times.
✓ Branch 11 taken 179598 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 4612715 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
9045834 thd->dd_client()->acquire(share->db.str, share->table_name.str,
3403 &table_def)) {
3404 // Error is reported by the dictionary subsystem.
3405 goto err_lock;
3406 }
3407
3408
7/8
✓ Branch 0 taken 4433115 times.
✓ Branch 1 taken 179600 times.
✓ Branch 2 taken 4433112 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 4433107 times.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 4612707 times.
4612715 if (table_def && table_def->hidden() == dd::Abstract_table::HT_HIDDEN_SE) {
3409
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db,
3410 table_list->table_name);
3411 5 goto err_lock;
3412 }
3413
3414 /* make a new table */
3415
2/4
✓ Branch 0 taken 4612712 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4612712 times.
4612707 if (!(table = (TABLE *)my_malloc(key_memory_TABLE, sizeof(*table),
3416 MYF(MY_WME))))
3417 goto err_lock;
3418
3419
1/2
✓ Branch 0 taken 4612678 times.
✗ Branch 1 not taken.
4612712 error = open_table_from_share(
3420 thd, share, alias,
3421
2/2
✓ Branch 0 taken 179599 times.
✓ Branch 1 taken 4433113 times.
4612712 ((flags & MYSQL_OPEN_NO_NEW_TABLE_IN_SE)
3422 ? 0
3423 : ((uint)(HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
3424 HA_TRY_READ_ONLY))),
3425 EXTRA_RECORD, thd->open_options, table, false, table_def);
3426
3427
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 4612203 times.
4612678 if (error) {
3428 475 destroy(table);
3429
1/2
✓ Branch 0 taken 475 times.
✗ Branch 1 not taken.
475 my_free(table);
3430
3431
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 475 times.
475 if (error == 7)
3432 (void)ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER,
3433 table_list);
3434
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 452 times.
475 else if (error == 8)
3435
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 (void)ot_ctx->request_backoff_action(
3436 Open_table_context::OT_FIX_ROW_TYPE, table_list);
3437
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 447 times.
452 else if (share->crashed)
3438
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 (void)ot_ctx->request_backoff_action(Open_table_context::OT_REPAIR,
3439 table_list);
3440 475 goto err_lock;
3441
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4612203 times.
4612203 } else if (share->crashed) {
3442 switch (thd->lex->sql_command) {
3443 case SQLCOM_ALTER_TABLE:
3444 case SQLCOM_REPAIR:
3445 case SQLCOM_CHECK:
3446 case SQLCOM_SHOW_CREATE:
3447 break;
3448 default:
3449 closefrm(table, false);
3450 destroy(table);
3451 my_free(table);
3452 my_error(ER_CRASHED_ON_USAGE, MYF(0), share->table_name.str);
3453 goto err_lock;
3454 }
3455 }
3456
3457
2/4
✓ Branch 0 taken 4612210 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4612210 times.
4612203 if (open_table_entry_fini(thd, share, table_def, table)) {
3458 closefrm(table, false);
3459 destroy(table);
3460 my_free(table);
3461 goto err_lock;
3462 }
3463
2/2
✓ Branch 0 taken 4612235 times.
✓ Branch 1 taken 480 times.
4612690 }
3464 {
3465 /* Add new TABLE object to table cache for this connection. */
3466 4612235 Table_cache *tc = table_cache_manager.get_cache(thd);
3467
3468
1/2
✓ Branch 0 taken 4612232 times.
✗ Branch 1 not taken.
4612233 tc->lock();
3469
3470
2/4
✓ Branch 0 taken 4612228 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4612228 times.
4612232 if (tc->add_used_table(thd, table)) {
3471 tc->unlock();
3472 goto err_lock;
3473 }
3474
1/2
✓ Branch 0 taken 4612236 times.
✗ Branch 1 not taken.
4612228 tc->unlock();
3475 }
3476 4612236 thd->status_var.table_open_cache_misses++;
3477
3478 117481865 table_found:
3479
3480 352423502 if (!backup_protection_acquired &&
3481
2/2
✓ Branch 0 taken 33939530 times.
✓ Branch 1 taken 83519922 times.
117459452 table_list->mdl_request.type >= MDL_SHARED_WRITE &&
3482
2/2
✓ Branch 0 taken 33350200 times.
✓ Branch 1 taken 589330 times.
33939530 !(flags & (MYSQL_LOCK_LOG_TABLE | MYSQL_OPEN_HAS_MDL_LOCK)) &&
3483
6/8
✓ Branch 0 taken 117459452 times.
✓ Branch 1 taken 22413 times.
✓ Branch 2 taken 33350252 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33350305 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 401371 times.
✓ Branch 7 taken 117080814 times.
268291890 share->db_type() &&
3484
3/4
✓ Branch 0 taken 33350573 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 401349 times.
✓ Branch 3 taken 32949224 times.
33350305 !(share->db_type()->flags & HTON_SUPPORTS_ONLINE_BACKUPS)) {
3485
4/4
✓ Branch 0 taken 401444 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 71 times.
✓ Branch 3 taken 401441 times.
802824 if (thd->backup_tables_lock.abort_if_acquired() ||
3486
3/4
✓ Branch 0 taken 401453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 401441 times.
401444 thd->backup_tables_lock.acquire_protection(thd, MDL_STATEMENT,
3487 ot_ctx->get_timeout())) {
3488 71 Table_cache *tc = table_cache_manager.get_cache(thd);
3489
3490
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
71 tc->lock();
3491
3492
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
71 tc->release_table(thd, table);
3493
3494
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
71 tc->unlock();
3495
3496
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
71 table->file->unbind_psi();
3497
3498 71 return true;
3499 }
3500 }
3501
3502 117482255 table->mdl_ticket = mdl_ticket;
3503
3504 117482255 table->next = thd->open_tables; /* Link into simple list */
3505
1/2
✓ Branch 0 taken 117481224 times.
✗ Branch 1 not taken.
117482255 thd->set_open_tables(table);
3506
3507 117481224 table->reginfo.lock_type = TL_READ; /* Assume read */
3508
3509 117526076 reset:
3510
1/2
✓ Branch 0 taken 117525145 times.
✗ Branch 1 not taken.
117526076 table->reset();
3511
1/2
✓ Branch 0 taken 117525586 times.
✗ Branch 1 not taken.
117525145 table->set_created();
3512 /*
3513 Check that there is no reference to a condition from an earlier query
3514 (cf. Bug#58553).
3515 */
3516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117525586 times.
117525586 assert(table->file->pushed_cond == nullptr);
3517
3518 // Table is not a derived table and not a non-updatable view:
3519 117525586 table_list->set_updatable();
3520 117524932 table_list->set_insertable();
3521
3522 117525313 table_list->table = table;
3523
3524 /*
3525 Position for each partition in the bitmap is read from the Handler_share
3526 instance of the table. In MYSQL_OPEN_NO_NEW_TABLE_IN_SE mode, table is not
3527 opened in the SE and Handler_share instance for it is not created. Hence
3528 skipping partitions bitmap setting in the MYSQL_OPEN_NO_NEW_TABLE_IN_SE
3529 mode.
3530 */
3531
2/2
✓ Branch 0 taken 117330334 times.
✓ Branch 1 taken 194979 times.
117525313 if (!(flags & MYSQL_OPEN_NO_NEW_TABLE_IN_SE)) {
3532
2/2
✓ Branch 0 taken 183075 times.
✓ Branch 1 taken 117147259 times.
117330334 if (table->part_info) {
3533 /* Set all [named] partitions as used. */
3534
3/4
✓ Branch 0 taken 183075 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 183069 times.
183075 if (table->part_info->set_partition_bitmaps(table_list)) return true;
3535
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 117147258 times.
117147259 } else if (table_list->partition_names) {
3536 /* Don't allow PARTITION () clause on a nonpartitioned table */
3537
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_PARTITION_CLAUSE_ON_NONPARTITIONED, MYF(0));
3538 1 return true;
3539 }
3540 }
3541
3542
1/2
✓ Branch 0 taken 117526551 times.
✗ Branch 1 not taken.
117525306 table->init(thd, table_list);
3543
3544 /* Request a read lock for implicitly opened P_S tables. */
3545
8/8
✓ Branch 0 taken 47169 times.
✓ Branch 1 taken 117479432 times.
✓ Branch 2 taken 42864 times.
✓ Branch 3 taken 4305 times.
✓ Branch 4 taken 698 times.
✓ Branch 5 taken 41812 times.
✓ Branch 6 taken 698 times.
✓ Branch 7 taken 117525549 times.
117569061 if (in_LTM(thd) && table_list->table->file->get_lock_type() == F_UNLCK &&
3546 42864 belongs_to_p_s(table_list)) {
3547
1/2
✓ Branch 0 taken 794 times.
✗ Branch 1 not taken.
698 table_list->table->file->ha_external_lock(thd, F_RDLCK);
3548 }
3549
3550 117526351 return false;
3551
3552 497 err_lock:
3553
1/2
✓ Branch 0 taken 497 times.
✗ Branch 1 not taken.
497 mysql_mutex_lock(&LOCK_open);
3554
1/2
✓ Branch 0 taken 497 times.
✗ Branch 1 not taken.
497 release_table_share(share);
3555
1/2
✓ Branch 0 taken 497 times.
✗ Branch 1 not taken.
497 mysql_mutex_unlock(&LOCK_open);
3556
3557 497 return true;
3558 118828766 }
3559
3560 /**
3561 Find table in the list of open tables.
3562
3563 @param list List of TABLE objects to be inspected.
3564 @param db Database name
3565 @param table_name Table name
3566
3567 @return Pointer to the TABLE object found, 0 if no table found.
3568 */
3569
3570 1485 TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name) {
3571 char key[MAX_DBKEY_LENGTH];
3572
1/2
✓ Branch 0 taken 1485 times.
✗ Branch 1 not taken.
1485 size_t key_length = create_table_def_key(db, table_name, key);
3573
3574
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 38 times.
1648 for (TABLE *table = list; table; table = table->next) {
3575
2/2
✓ Branch 0 taken 1572 times.
✓ Branch 1 taken 38 times.
1610 if (table->s->table_cache_key.length == key_length &&
3576
2/2
✓ Branch 0 taken 1447 times.
✓ Branch 1 taken 125 times.
1572 !memcmp(table->s->table_cache_key.str, key, key_length))
3577 1447 return table;
3578 }
3579 38 return (nullptr);
3580 }
3581
3582 /**
3583 Find instance of TABLE with upgradable or exclusive metadata
3584 lock from the list of open tables, emit error if no such table
3585 found.
3586
3587 @param thd Thread context
3588 @param db Database name.
3589 @param table_name Name of table.
3590 @param no_error Don't emit error if no suitable TABLE
3591 instance were found.
3592
3593 @note This function checks if the connection holds a global IX
3594 metadata lock. If no such lock is found, it is not safe to
3595 upgrade the lock and ER_TABLE_NOT_LOCKED_FOR_WRITE will be
3596 reported.
3597
3598 @return Pointer to TABLE instance with MDL_SHARED_UPGRADABLE
3599 MDL_SHARED_NO_WRITE, MDL_SHARED_NO_READ_WRITE, or
3600 MDL_EXCLUSIVE metadata lock, NULL otherwise.
3601 */
3602
3603 1469 TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
3604 const char *table_name, bool no_error) {
3605 1469 TABLE *tab = find_locked_table(thd->open_tables, db, table_name);
3606
3607
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 1446 times.
1469 if (!tab) {
3608
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 if (!no_error) my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_name);
3609 23 return nullptr;
3610 }
3611
3612 /*
3613 It is not safe to upgrade the metadata lock without a global IX lock.
3614 This can happen with FLUSH TABLES <list> WITH READ LOCK as we in these
3615 cases don't take a global IX lock in order to be compatible with
3616 global read lock.
3617 */
3618
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 1425 times.
1446 if (!thd->mdl_context.owns_equal_or_stronger_lock(MDL_key::GLOBAL, "", "",
3619 MDL_INTENTION_EXCLUSIVE)) {
3620
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 if (!no_error) my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_name);
3621 21 return nullptr;
3622 }
3623
3624 1425 while (tab->mdl_ticket != nullptr &&
3625
4/6
✓ Branch 0 taken 1425 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 1411 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1425 times.
1439 !tab->mdl_ticket->is_upgradable_or_exclusive() &&
3626
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 (tab = find_locked_table(tab->next, db, table_name)))
3627 continue;
3628
3629
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 1411 times.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
1425 if (!tab && !no_error)
3630 14 my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_name);
3631
3632 1425 return tab;
3633 }
3634
3635 /*
3636 Function to assign a new table map id to a table share.
3637
3638 PARAMETERS
3639
3640 share - Pointer to table share structure
3641
3642 DESCRIPTION
3643
3644 We are intentionally not checking that share->mutex is locked
3645 since this function should only be called when opening a table
3646 share and before it is entered into the table_def_cache (meaning
3647 that it cannot be fetched by another thread, even accidentally).
3648
3649 PRE-CONDITION(S)
3650
3651 share is non-NULL
3652 The LOCK_open mutex is locked.
3653
3654 POST-CONDITION(S)
3655
3656 share->table_map_id is given a value that with a high certainty is
3657 not used by any other table (the only case where a table id can be
3658 reused is on wrap-around, which means more than 2^48 table
3659 share opens have been executed while one table was open all the
3660 time).
3661
3662 */
3663 static Table_id last_table_id;
3664
3665 2306306 void assign_new_table_id(TABLE_SHARE *share) {
3666
1/2
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
2306306 DBUG_TRACE;
3667
3668 /* Preconditions */
3669
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2306306 times.
2306306 assert(share != nullptr);
3670 2306306 mysql_mutex_assert_owner(&LOCK_open);
3671
3672
3/4
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 2306287 times.
2306306 DBUG_EXECUTE_IF("dbug_table_map_id_500", last_table_id = 500;);
3673
3/4
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2306305 times.
2306306 DBUG_EXECUTE_IF("dbug_table_map_id_4B_UINT_MAX+501",
3674 last_table_id = 501ULL + UINT_MAX;);
3675
3/4
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2306305 times.
2306306 DBUG_EXECUTE_IF("dbug_table_map_id_6B_UINT_MAX",
3676 last_table_id = (~0ULL >> 16););
3677
3678 2306306 share->table_map_id = last_table_id++;
3679
5/8
✓ Branch 0 taken 2306306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2306306 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 70 times.
✓ Branch 5 taken 2306236 times.
✓ Branch 6 taken 70 times.
✗ Branch 7 not taken.
2306306 DBUG_PRINT("info", ("table_id=%llu", share->table_map_id.id()));
3680 2306306 }
3681
3682 /**
3683 Compare metadata versions of an element obtained from the table
3684 definition cache and its corresponding node in the parse tree.
3685
3686 @details If the new and the old values mismatch, invoke
3687 Metadata_version_observer.
3688 At prepared statement prepare, all TABLE_LIST version values are
3689 NULL and we always have a mismatch. But there is no observer set
3690 in THD, and therefore no error is reported. Instead, we update
3691 the value in the parse tree, effectively recording the original
3692 version.
3693 At prepared statement execute, an observer may be installed. If
3694 there is a version mismatch, we push an error and return true.
3695
3696 For conventional execution (no prepared statements), the
3697 observer is never installed.
3698
3699 @sa Execute_observer
3700 @sa check_prepared_statement() to see cases when an observer is installed
3701 @sa TABLE_LIST::is_table_ref_id_equal()
3702 @sa TABLE_SHARE::get_table_ref_id()
3703
3704 @param[in] thd used to report errors
3705 @param[in,out] tables TABLE_LIST instance created by the parser
3706 Metadata version information in this object
3707 is updated upon success.
3708 @param[in] table_share an element from the table definition cache
3709
3710 @retval true an error, which has been reported
3711 @retval false success, version in TABLE_LIST has been updated
3712 */
3713
3714 118484657 static bool check_and_update_table_version(THD *thd, TABLE_LIST *tables,
3715 TABLE_SHARE *table_share) {
3716
2/2
✓ Branch 0 taken 112856873 times.
✓ Branch 1 taken 5628323 times.
118484657 if (!tables->is_table_ref_id_equal(table_share)) {
3717 /*
3718 Version of the table share is different from the
3719 previous execution of the prepared statement, and it is
3720 unacceptable for this SQLCOM.
3721 */
3722
2/2
✓ Branch 0 taken 18299 times.
✓ Branch 1 taken 112838629 times.
112856873 if (ask_to_reprepare(thd)) return true;
3723 /* Always maintain the latest version and type */
3724 112838629 tables->set_table_ref_id(table_share);
3725 }
3726 118467044 return false;
3727 }
3728
3729 /**
3730 Compares versions of a stored routine obtained from the sp cache
3731 and the version used at prepare.
3732
3733 @details If the new and the old values mismatch, invoke
3734 Metadata_version_observer.
3735 At prepared statement prepare, all Sroutine_hash_entry version values
3736 are NULL and we always have a mismatch. But there is no observer set
3737 in THD, and therefore no error is reported. Instead, we update
3738 the value in Sroutine_hash_entry, effectively recording the original
3739 version.
3740 At prepared statement execute, an observer may be installed. If
3741 there is a version mismatch, we push an error and return true.
3742
3743 For conventional execution (no prepared statements), the
3744 observer is never installed.
3745
3746 @param[in] thd used to report errors
3747 @param[in,out] rt pointer to stored routine entry in the
3748 parse tree
3749 @param[in] sp pointer to stored routine cache entry.
3750 Can be NULL if there is no such routine.
3751 @retval true an error, which has been reported
3752 @retval false success, version in Sroutine_hash_entry has been updated
3753 */
3754
3755 144393 static bool check_and_update_routine_version(THD *thd, Sroutine_hash_entry *rt,
3756 sp_head *sp) {
3757 144393 int64 spc_version = sp_cache_version();
3758 /* sp is NULL if there is no such routine. */
3759
2/2
✓ Branch 0 taken 144298 times.
✓ Branch 1 taken 95 times.
144393 int64 version = sp ? sp->sp_cache_version() : spc_version;
3760 /*
3761 If the version in the parse tree is stale,
3762 or the version in the cache is stale and sp is not used,
3763 we need to reprepare.
3764 Sic: version != spc_version <--> sp is not NULL.
3765 */
3766
6/6
✓ Branch 0 taken 43191 times.
✓ Branch 1 taken 101202 times.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 43171 times.
✓ Branch 4 taken 101221 times.
✓ Branch 5 taken 43172 times.
144413 if (rt->m_cache_version != version ||
3767
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 1 times.
20 (version != spc_version && !sp->is_invoked())) {
3768 /*
3769 Version of the sp cache is different from the
3770 previous execution of the prepared statement, and it is
3771 unacceptable for this SQLCOM.
3772 */
3773
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 101190 times.
101221 if (ask_to_reprepare(thd)) return true;
3774 /* Always maintain the latest cache version. */
3775 101190 rt->m_cache_version = version;
3776 }
3777 144362 return false;
3778 }
3779
3780 /**
3781 Open view by getting its definition from disk (and table cache in future).
3782
3783 @param thd Thread handle
3784 @param table_list TABLE_LIST with db, table_name & belong_to_view
3785 @param cache_key Key for table definition cache
3786 @param cache_key_length Length of cache_key
3787
3788 @todo This function is needed for special handling of views under
3789 LOCK TABLES. We probably should get rid of it in long term.
3790
3791 @return false if success, true - otherwise.
3792 */
3793
3794 529 static bool tdc_open_view(THD *thd, TABLE_LIST *table_list,
3795 const char *cache_key, size_t cache_key_length) {
3796 TABLE_SHARE *share;
3797
3798 529 mysql_mutex_lock(&LOCK_open);
3799
3800
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 529 times.
529 if (!(share = get_table_share(thd, table_list->db, table_list->table_name,
3801 cache_key, cache_key_length, true))) {
3802 mysql_mutex_unlock(&LOCK_open);
3803 return true;
3804 }
3805
3806 /*
3807 Check TABLE_SHARE-version of view only if we have been instructed to do
3808 so. We do not need to check the version if we're executing CREATE VIEW or
3809 ALTER VIEW statements.
3810
3811 In the future, this functionality should be moved out from
3812 tdc_open_view(), and tdc_open_view() should became a part of a clean
3813 table-definition-cache interface.
3814 */
3815
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 522 times.
529 if (check_and_update_table_version(thd, table_list, share)) {
3816 7 release_table_share(share);
3817 7 mysql_mutex_unlock(&LOCK_open);
3818 7 return true;
3819 }
3820
3821
1/2
✓ Branch 0 taken 522 times.
✗ Branch 1 not taken.
522 if (share->is_view) {
3822 522 bool view_open_result = open_and_read_view(thd, share, table_list);
3823
3824 522 release_table_share(share);
3825 522 mysql_mutex_unlock(&LOCK_open);
3826
3827
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 522 times.
522 if (view_open_result) return true;
3828
3829 522 return parse_view_definition(thd, table_list);
3830 }
3831
3832 my_error(ER_WRONG_OBJECT, MYF(0), share->db.str, share->table_name.str,
3833 "VIEW");
3834 release_table_share(share);
3835 mysql_mutex_unlock(&LOCK_open);
3836 return true;
3837 }
3838
3839 /**
3840 Finalize the process of TABLE creation by loading table triggers
3841 and taking action if a HEAP table content was emptied implicitly.
3842 */
3843
3844 4612229 static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share,
3845 const dd::Table *table, TABLE *entry) {
3846
6/6
✓ Branch 0 taken 4432631 times.
✓ Branch 1 taken 179598 times.
✓ Branch 2 taken 36779 times.
✓ Branch 3 taken 4395845 times.
✓ Branch 4 taken 36779 times.
✓ Branch 5 taken 4575443 times.
4612229 if (table != nullptr && table->has_trigger()) {
3847 36779 Table_trigger_dispatcher *d = Table_trigger_dispatcher::create(entry);
3848
3849
3/6
✓ Branch 0 taken 36779 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36778 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 36778 times.
36779 if (!d || d->check_n_load(thd, *table)) {
3850 destroy(d);
3851 return true;
3852 }
3853
3854 36778 entry->triggers = d;
3855 }
3856
3857 /*
3858 If we are here, there was no fatal error (but error may be still
3859 uninitialized).
3860
3861 Ignore handling implicit_emptied property (which is only for heap
3862 tables) when I_S query is opening this table to read table statistics.
3863 The reason for avoiding this is that the
3864 mysql_bin_log.write_dml_directly() invokes a commit(). And this commit
3865 is not expected to be invoked when fetching I_S table statistics.
3866 */
3867
4/4
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 4612158 times.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 4612159 times.
4612284 if (unlikely(entry->file->implicit_emptied) &&
3868
3/4
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 1 times.
63 (!thd->lex || !thd->lex->m_IS_table_stats.is_reading_stats_by_open())) {
3869 62 entry->file->implicit_emptied = false;
3870
1/2
✓ Branch 0 taken 70 times.
✗ Branch 1 not taken.
62 if (mysql_bin_log.is_open()) {
3871 70 bool result = false;
3872 70 String temp_buf;
3873
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 result = temp_buf.append("TRUNCATE TABLE ");
3874
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 append_identifier(thd, &temp_buf, share->db.str, strlen(share->db.str));
3875
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 result = temp_buf.append(".");
3876
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 append_identifier(thd, &temp_buf, share->table_name.str,
3877 strlen(share->table_name.str));
3878
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 result = temp_buf.append(
3879 " /* generated by server, implicitly emptying in-memory table */");
3880
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (result) {
3881 /*
3882 As replication is maybe going to be corrupted, we need to warn the
3883 DBA on top of warning the client (which will automatically be done
3884 because of MYF(MY_WME) in my_malloc() above).
3885 */
3886 LogErr(ERROR_LEVEL,
3887 ER_BINLOG_OOM_WRITING_DELETE_WHILE_OPENING_HEAP_TABLE,
3888 share->db.str, share->table_name.str);
3889 destroy(entry->triggers);
3890 return true;
3891 }
3892 /*
3893 Create a new THD object for binary logging the statement which
3894 implicitly empties the in-memory table.
3895 */
3896
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 THD new_thd;
3897 56 new_thd.thread_stack = (char *)&thd;
3898
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 new_thd.set_new_thread_id();
3899
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 new_thd.store_globals();
3900
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 new_thd.set_db(thd->db());
3901 56 new_thd.variables.gtid_next.set_automatic();
3902 56 Global_THD_manager *thd_manager = Global_THD_manager::get_instance();
3903
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 thd_manager->add_thd(&new_thd);
3904 56 result = mysql_bin_log.write_stmt_directly(
3905
2/4
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
56 &new_thd, temp_buf.c_ptr_safe(), temp_buf.length(), SQLCOM_TRUNCATE);
3906
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 new_thd.restore_globals();
3907
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 thd->store_globals();
3908
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 new_thd.release_resources();
3909
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 thd_manager->remove_thd(&new_thd);
3910 56 return result;
3911 56 }
3912 }
3913 4612151 return false;
3914 }
3915
3916 /**
3917 Auxiliary routine which is used for performing automatic table repair.
3918 */
3919
3920 4 static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) {
3921 const char *cache_key;
3922 size_t cache_key_length;
3923 TABLE_SHARE *share;
3924 TABLE *entry;
3925 4 bool result = true;
3926
3927
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 cache_key_length = get_table_def_key(table_list, &cache_key);
3928
3929
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 thd->clear_error();
3930
3931
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 mysql_mutex_lock(&LOCK_open);
3932
3933
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if (!(share = get_table_share(thd, table_list->db, table_list->table_name,
3934 cache_key, cache_key_length, true)))
3935 goto end_unlock;
3936
3937
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (share->is_view) {
3938 release_table_share(share);
3939 goto end_unlock;
3940 }
3941
3942 4 if (!(entry =
3943
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 (TABLE *)my_malloc(key_memory_TABLE, sizeof(TABLE), MYF(MY_WME)))) {
3944 release_table_share(share);
3945 goto end_unlock;
3946 }
3947
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 mysql_mutex_unlock(&LOCK_open);
3948
3949
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (open_table_from_share(thd, share, table_list->alias,
3950 (uint)(HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3951 HA_GET_INDEX | HA_TRY_READ_ONLY),
3952 EXTRA_RECORD, ha_open_options | HA_OPEN_FOR_REPAIR,
3953 4 entry, false, nullptr) ||
3954
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
8 !entry->file ||
3955
4/8
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
4 (entry->file->is_crashed() && entry->file->ha_check_and_repair(thd))) {
3956 /* Give right error message */
3957 thd->clear_error();
3958 my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str);
3959 LogErr(ERROR_LEVEL, ER_FAILED_TO_REPAIR_TABLE, share->db.str,
3960 share->table_name.str);
3961 if (entry->file) closefrm(entry, false);
3962 } else {
3963
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 thd->clear_error(); // Clear error message
3964
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 closefrm(entry, false);
3965 4 result = false;
3966 }
3967
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 my_free(entry);
3968
3969
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 table_cache_manager.lock_all_and_tdc();
3970
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 release_table_share(share);
3971 /* Remove the repaired share from the table cache. */
3972
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db,
3973 table_list->table_name, true);
3974
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 table_cache_manager.unlock_all_and_tdc();
3975 4 return result;
3976 end_unlock:
3977 mysql_mutex_unlock(&LOCK_open);
3978 return result;
3979 }
3980
3981 /**
3982 Error handler class for suppressing HA_ERR_ROW_FORMAT_CHANGED errors from SE.
3983 */
3984
3985 class Fix_row_type_error_handler : public Internal_error_handler {
3986 public:
3987 21 bool handle_condition(THD *, uint sql_errno, const char *,
3988 Sql_condition::enum_severity_level *,
3989 const char *) override {
3990
2/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
21 return sql_errno == ER_GET_ERRNO && my_errno() == HA_ERR_ROW_FORMAT_CHANGED;
3991 }
3992 };
3993
3994 /**
3995 Auxiliary routine for automatically updating row format for the table.
3996 */
3997
3998 21 static bool fix_row_type(THD *thd, TABLE_LIST *table_list) {
3999 const char *cache_key;
4000
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 size_t cache_key_length = get_table_def_key(table_list, &cache_key);
4001
4002
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 thd->clear_error();
4003
4004 TABLE_SHARE *share;
4005
4006 {
4007 /*
4008 Hold LOCK_open until we can keep it and are likely to
4009 release TABLE_SHARE on return.
4010 */
4011 21 MUTEX_LOCK(lock_open_guard, &LOCK_open);
4012
4013 21 No_such_table_error_handler no_such_table_handler;
4014
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 thd->push_internal_handler(&no_such_table_handler);
4015
4016
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 share = get_table_share(thd, table_list->db, table_list->table_name,
4017 cache_key, cache_key_length, true);
4018
4019
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 thd->pop_internal_handler();
4020
4021
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (!share) {
4022 /*
4023 Somebody managed to drop table after we have performed back-off
4024 before trying to fix row format for the table. Such situation is
4025 quite unlikely but theoretically possible. Do not report error
4026 (silence it using error handler), let the caller try to reopen
4027 tables and handle missing table in appropriate way (e.g. ignore
4028 this fact it if the table comes from prelocking list).
4029 */
4030 if (no_such_table_handler.safely_trapped_errors()) return false;
4031
4032 return true;
4033 }
4034
4035
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (share->is_view) {
4036 /*
4037 Somebody managed to replace our table with a view after we
4038 have performed back-off before trying to fix row format for
4039 the table. Such situation is quite unlikely but is OK.
4040 Do not report error, let the caller try to reopen tables.
4041 */
4042 release_table_share(share);
4043 return false;
4044 }
4045
2/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
21 }
4046
4047 21 int error = 0;
4048
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client());
4049 21 dd::Table *table_def = nullptr;
4050
4/8
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 21 times.
21 if (thd->dd_client()->acquire_for_modification(
4051 share->db.str, share->table_name.str, &table_def))
4052 error = 1;
4053
4054
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 assert(table_def != nullptr);
4055
4056 /*
4057 Silence expected HA_ERR_ROW_FORMAT_CHANGED errors.
4058 */
4059 21 Fix_row_type_error_handler err_handler;
4060
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 thd->push_internal_handler(&err_handler);
4061
4062
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 TABLE tmp_table;
4063
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 if (error == 0)
4064
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 error = open_table_from_share(thd, share, table_list->alias,
4065 (uint)(HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
4066 HA_GET_INDEX | HA_TRY_READ_ONLY),
4067 EXTRA_RECORD, ha_open_options, &tmp_table,
4068 false, table_def);
4069
4070
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 thd->pop_internal_handler();
4071
4072
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 if (error == 8) {
4073 21 Disable_autocommit_guard autocommit_guard(thd);
4074
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 HA_CREATE_INFO create_info;
4075 21 create_info.row_type = share->row_type;
4076 21 create_info.table_options = share->db_options_in_use;
4077
4078
2/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
21 handler *file = get_new_handler(share, share->m_part_info != nullptr,
4079 thd->mem_root, share->db_type());
4080
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 if (file != nullptr) {
4081
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 row_type correct_row_type = file->get_real_row_type(&create_info);
4082
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 bool result = dd::fix_row_type(thd, table_def, correct_row_type);
4083 21 destroy(file);
4084
4085
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (result) {
4086 trans_rollback_stmt(thd);
4087 trans_rollback(thd);
4088 } else {
4089
4/8
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 21 times.
21 result = trans_commit_stmt(thd) || trans_commit(thd);
4090
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 if (!result) error = 0;
4091 }
4092 }
4093
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
21 } else if (error == 0)
4094 closefrm(&tmp_table, false);
4095
4096
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 table_cache_manager.lock_all_and_tdc();
4097
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 release_table_share(share);
4098 /*
4099 Remove the share from the table cache. So attempt to reopen table
4100 will construct its new version with correct real_row_type value.
4101 */
4102
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db,
4103 table_list->table_name, true);
4104
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 table_cache_manager.unlock_all_and_tdc();
4105 21 return error != 0;
4106 21 }
4107
4108 /** Open_table_context */
4109
4110 61342819 Open_table_context::Open_table_context(THD *thd, uint flags)
4111 61342819 : m_thd(thd),
4112 61342819 m_failed_table(nullptr),
4113 61342819 m_start_of_statement_svp(thd->mdl_context.mdl_savepoint()),
4114 122687788 m_timeout(flags & MYSQL_LOCK_IGNORE_TIMEOUT
4115
2/2
✓ Branch 0 taken 37733889 times.
✓ Branch 1 taken 23610005 times.
61343894 ? LONG_TIMEOUT
4116 37733889 : thd->variables.lock_wait_timeout),
4117 61343894 m_flags(flags),
4118 61343894 m_action(OT_NO_ACTION),
4119 61343894 m_has_locks(thd->mdl_context.has_locks()),
4120 61343915 m_has_protection_against_grl(false) {}
4121
4122 /**
4123 Check if we can back-off and set back off action if we can.
4124 Otherwise report and return error.
4125
4126 @retval true if back-off is impossible.
4127 @retval false if we can back off. Back off action has been set.
4128 */
4129
4130 57 bool Open_table_context::request_backoff_action(
4131 enum_open_table_action action_arg, TABLE_LIST *table) {
4132 /*
4133 A back off action may be one of four kinds:
4134
4135 * We met a broken table that needs repair, or a table that
4136 is not present on this MySQL server and needs re-discovery.
4137 To perform the action, we need an exclusive metadata lock on
4138 the table. Acquiring X lock while holding other shared
4139 locks can easily lead to deadlocks. We rely on MDL deadlock
4140 detector to discover them. If this is a multi-statement
4141 transaction that holds metadata locks for completed statements,
4142 we should keep these locks after discovery/repair.
4143 The action type in this case is OT_DISCOVER or OT_REPAIR.
4144 * We met a table that has outdated value in ROW_FORMAT column
4145 in the data-dictionary/value of TABLE_SHARE::real_row_type
4146 attribute, which need to be updated. To update the
4147 data-dictionary we not only need to acquire X lock on the
4148 table, but also need to commit the transaction. If there
4149 is an ongoing transaction (and some metadata locks acquired)
4150 we cannot proceed and report an error. The action type for
4151 this case is OT_FIX_ROW_TYPE.
4152 * Our attempt to acquire an MDL lock lead to a deadlock,
4153 detected by the MDL deadlock detector. The current
4154 session was chosen a victim. If this is a multi-statement
4155 transaction that holds metadata locks taken by completed
4156 statements, restarting locking for the current statement
4157 may lead to a livelock. Releasing locks of completed
4158 statements can not be done as will lead to violation
4159 of ACID. Thus, again, if m_has_locks is set,
4160 we report an error. Otherwise, when there are no metadata
4161 locks other than which belong to this statement, we can
4162 try to recover from error by releasing all locks and
4163 restarting the pre-locking.
4164 Similarly, a deadlock error can occur when the
4165 pre-locking process met a TABLE_SHARE that is being
4166 flushed, and unsuccessfully waited for the flush to
4167 complete. A deadlock in this case can happen, e.g.,
4168 when our session is holding a metadata lock that
4169 is being waited on by a session which is using
4170 the table which is being flushed. The only way
4171 to recover from this error is, again, to close all
4172 open tables, release all locks, and retry pre-locking.
4173 Action type name is OT_REOPEN_TABLES. Re-trying
4174 while holding some locks may lead to a livelock,
4175 and thus we don't do it.
4176 * Finally, this session has open TABLEs from different
4177 "generations" of the table cache. This can happen, e.g.,
4178 when, after this session has successfully opened one
4179 table used for a statement, FLUSH TABLES interfered and
4180 expelled another table used in it. FLUSH TABLES then
4181 blocks and waits on the table already opened by this
4182 statement.
4183 We detect this situation by ensuring that table cache
4184 version of all tables used in a statement is the same.
4185 If it isn't, all tables needs to be reopened.
4186 Note, that we can always perform a reopen in this case,
4187 even if we already have metadata locks, since we don't
4188 keep tables open between statements and a livelock
4189 is not possible.
4190 */
4191
6/6
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 29 times.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 21 times.
✓ Branch 5 taken 36 times.
109 if ((action_arg == OT_BACKOFF_AND_RETRY || action_arg == OT_FIX_ROW_TYPE) &&
4192
3/4
✓ Branch 0 taken 52 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 31 times.
52 (has_commit_order_manager(m_thd) || m_has_locks)) {
4193 21 my_error(ER_LOCK_DEADLOCK, MYF(0));
4194 21 m_thd->mark_transaction_to_rollback(true);
4195 21 return true;
4196 }
4197 /*
4198 If auto-repair or discovery are requested, a pointer to table
4199 list element must be provided.
4200 */
4201
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 10 times.
36 if (table) {
4202
4/6
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 21 times.
26 assert(action_arg == OT_DISCOVER || action_arg == OT_REPAIR ||
4203 action_arg == OT_FIX_ROW_TYPE);
4204 52 m_failed_table = new (m_thd->mem_root)
4205 TABLE_LIST(table->db, table->db_length, table->table_name,
4206
2/4
✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
26 table->table_name_length, table->alias, TL_WRITE);
4207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 if (m_failed_table == nullptr) return true;
4208 26 m_failed_table->mdl_request.set_type(MDL_EXCLUSIVE);
4209 }
4210 36 m_action = action_arg;
4211 36 return false;
4212 }
4213
4214 /**
4215 An error handler to mark transaction to rollback on DEADLOCK error
4216 during DISCOVER / REPAIR.
4217 */
4218 class MDL_deadlock_discovery_repair_handler : public Internal_error_handler {
4219 public:
4220 4 bool handle_condition(THD *thd, uint sql_errno, const char *,
4221 Sql_condition::enum_severity_level *,
4222 const char *) override {
4223
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (sql_errno == ER_LOCK_DEADLOCK) {
4224 1 thd->mark_transaction_to_rollback(true);
4225 }
4226 /*
4227 We have marked this transaction to rollback. Return false to allow
4228 error to be reported or handled by other handlers.
4229 */
4230 4 return false;
4231 }
4232 };
4233
4234 /**
4235 Recover from failed attempt of open table by performing requested action.
4236
4237 @pre This function should be called only with "action" != OT_NO_ACTION
4238 and after having called @sa close_tables_for_reopen().
4239
4240 @retval false - Success. One should try to open tables once again.
4241 @retval true - Error
4242 */
4243
4244 36 bool Open_table_context::recover_from_failed_open() {
4245
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 31 times.
36 if (m_action == OT_REPAIR) {
4246
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 DEBUG_SYNC(m_thd, "recover_ot_repair");
4247 }
4248
4249 /*
4250 Skip repair and discovery in IS-queries as they require X lock
4251 which could lead to delays or deadlock. Instead set
4252 ER_WARN_I_S_SKIPPED_TABLE which will be converted to a warning
4253 later.
4254 */
4255
3/4
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
36 if ((m_action == OT_REPAIR || m_action == OT_DISCOVER ||
4256
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 10 times.
31 m_action == OT_FIX_ROW_TYPE) &&
4257
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26 times.
26 (m_flags & MYSQL_OPEN_FAIL_ON_MDL_CONFLICT)) {
4258 my_error(ER_WARN_I_S_SKIPPED_TABLE, MYF(0),
4259 m_failed_table->mdl_request.key.db_name(),
4260 m_failed_table->mdl_request.key.name());
4261 return true;
4262 }
4263
4264 36 bool result = false;
4265 36 MDL_deadlock_discovery_repair_handler handler;
4266 /*
4267 Install error handler to mark transaction to rollback on DEADLOCK error.
4268 */
4269
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 m_thd->push_internal_handler(&handler);
4270
4271 /* Execute the action. */
4272
3/6
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 21 times.
✗ Branch 5 not taken.
36 switch (m_action) {
4273 10 case OT_BACKOFF_AND_RETRY:
4274 10 break;
4275 case OT_REOPEN_TABLES:
4276 break;
4277 case OT_DISCOVER: {
4278 if ((result = lock_table_names(m_thd, m_failed_table, nullptr,
4279 get_timeout(), 0)))
4280 break;
4281
4282 tdc_remove_table(m_thd, TDC_RT_REMOVE_ALL, m_failed_table->db,
4283 m_failed_table->table_name, false);
4284 if (ha_create_table_from_engine(m_thd, m_failed_table->db,
4285 m_failed_table->table_name)) {
4286 result = true;
4287 break;
4288 }
4289
4290 m_thd->get_stmt_da()->reset_condition_info(m_thd);
4291 m_thd->clear_error(); // Clear error message
4292 /*
4293 Rollback to start of the current statement to release exclusive lock
4294 on table which was discovered but preserve locks from previous
4295 statements in current transaction.
4296 */
4297 m_thd->mdl_context.rollback_to_savepoint(start_of_statement_svp());
4298 break;
4299 }
4300 5 case OT_REPAIR: {
4301
3/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
5 if ((result = lock_table_names(m_thd, m_failed_table, nullptr,
4302 get_timeout(), 0)))
4303 1 break;
4304
4305 4 tdc_remove_table(m_thd, TDC_RT_REMOVE_ALL, m_failed_table->db,
4306
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 m_failed_table->table_name, false);
4307
4308
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 result = auto_repair_table(m_thd, m_failed_table);
4309 /*
4310 Rollback to start of the current statement to release exclusive lock
4311 on table which was discovered but preserve locks from previous
4312 statements in current transaction.
4313 */
4314
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 m_thd->mdl_context.rollback_to_savepoint(start_of_statement_svp());
4315 4 break;
4316 }
4317 21 case OT_FIX_ROW_TYPE: {
4318 /*
4319 Since we are going to commit changes to the data-dictionary there
4320 should not be any ongoing transaction.
4321 We already have checked that the connection holds no metadata locks
4322 earlier.
4323 Still there can be transaction started by START TRANSACTION, which
4324 we don't have right to implicitly finish (even more interesting case
4325 is START TRANSACTION WITH CONSISTENT SNAPSHOT). Hence explicit check
4326 for active transaction.
4327 */
4328
2/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 21 times.
21 assert(!m_thd->mdl_context.has_locks());
4329
4330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (m_thd->in_active_multi_stmt_transaction()) {
4331 my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
4332 result = true;
4333 break;
4334 }
4335
4336
2/4
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 21 times.
21 if ((result = lock_table_names(m_thd, m_failed_table, nullptr,
4337 get_timeout(), 0)))
4338 break;
4339
4340
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 result = fix_row_type(m_thd, m_failed_table);
4341
4342
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 m_thd->mdl_context.release_transactional_locks();
4343 21 break;
4344 }
4345 default:
4346 assert(0);
4347 }
4348
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 m_thd->pop_internal_handler();
4349 /*
4350 Reset the pointers to conflicting MDL request and the
4351 TABLE_LIST element, set when we need auto-discovery or repair,
4352 for safety.
4353 */
4354 36 m_failed_table = nullptr;
4355 /*
4356 Reset flag indicating that we have already acquired protection
4357 against GRL. It is no longer valid as the corresponding lock was
4358 released by close_tables_for_reopen().
4359 */
4360 36 m_has_protection_against_grl = false;
4361 /* Prepare for possible another back-off. */
4362 36 m_action = OT_NO_ACTION;
4363 36 return result;
4364 36 }
4365
4366 /*
4367 Return a appropriate read lock type given a table object.
4368
4369 @param thd Thread context
4370 @param prelocking_ctx Prelocking context.
4371 @param table_list Table list element for table to be locked.
4372 @param routine_modifies_data
4373 Some routine that is invoked by statement
4374 modifies data.
4375
4376 @remark Due to a statement-based replication limitation, statements such as
4377 INSERT INTO .. SELECT FROM .. and CREATE TABLE .. SELECT FROM need
4378 to grab a TL_READ_NO_INSERT lock on the source table in order to
4379 prevent the replication of a concurrent statement that modifies the
4380 source table. If such a statement gets applied on the slave before
4381 the INSERT .. SELECT statement finishes, data on the master could
4382 differ from data on the slave and end-up with a discrepancy between
4383 the binary log and table state.
4384 This also applies to SELECT/SET/DO statements which use stored
4385 functions. Calls to such functions are going to be logged as a
4386 whole and thus should be serialized against concurrent changes
4387 to tables used by those functions. This is avoided when functions
4388 do not modify data but only read it, since in this case nothing is
4389 written to the binary log. Argument routine_modifies_data
4390 denotes the same. So effectively, if the statement is not a
4391 LOCK TABLE, not a update query and routine_modifies_data is false
4392 then prelocking_placeholder does not take importance.
4393
4394 Furthermore, this does not apply to I_S and log tables as it's
4395 always unsafe to replicate such tables under statement-based
4396 replication as the table on the slave might contain other data
4397 (ie: general_log is enabled on the slave). The statement will
4398 be marked as unsafe for SBR in decide_logging_format().
4399 @remark Note that even in prelocked mode it is important to correctly
4400 determine lock type value. In this mode lock type is passed to
4401 handler::start_stmt() method and can be used by storage engine,
4402 for example, to determine what kind of row locks it should acquire
4403 when reading data from the table.
4404 */
4405
4406 4231800 thr_lock_type read_lock_type_for_table(THD *thd,
4407 Query_tables_list *prelocking_ctx,
4408 TABLE_LIST *table_list,
4409 bool routine_modifies_data) {
4410 /*
4411 In cases when this function is called for a sub-statement executed in
4412 prelocked mode we can't rely on OPTION_BIN_LOG flag in THD::options
4413 bitmap to determine that binary logging is turned on as this bit can
4414 be cleared before executing sub-statement. So instead we have to look
4415 at THD::variables::sql_log_bin member.
4416 */
4417
4/4
✓ Branch 0 taken 3707036 times.
✓ Branch 1 taken 524766 times.
✓ Branch 2 taken 3578460 times.
✓ Branch 3 taken 128576 times.
4231800 bool log_on = mysql_bin_log.is_open() && thd->variables.sql_log_bin;
4418
4419 /*
4420 When we do not write to binlog or when we use row based replication,
4421 it is safe to use a weaker lock.
4422 */
4423
4/4
✓ Branch 0 taken 3578459 times.
✓ Branch 1 taken 653343 times.
✓ Branch 2 taken 2962089 times.
✓ Branch 3 taken 616370 times.
4231802 if (log_on == false || thd->variables.binlog_format == BINLOG_FORMAT_ROW)
4424 3615432 return TL_READ;
4425
4426
2/2
✓ Branch 0 taken 616120 times.
✓ Branch 1 taken 250 times.
616370 if ((table_list->table->s->table_category == TABLE_CATEGORY_LOG) ||
4427
2/2
✓ Branch 0 taken 615748 times.
✓ Branch 1 taken 372 times.
616120 (table_list->table->s->table_category == TABLE_CATEGORY_RPL_INFO) ||
4428
2/2
✓ Branch 0 taken 615700 times.
✓ Branch 1 taken 48 times.
615748 (table_list->table->s->table_category == TABLE_CATEGORY_GTID) ||
4429
2/2
✓ Branch 0 taken 82706 times.
✓ Branch 1 taken 532994 times.
615700 (table_list->table->s->table_category == TABLE_CATEGORY_PERFORMANCE))
4430 83376 return TL_READ;
4431
4432 // SQL queries which updates data need a stronger lock.
4433
2/2
✓ Branch 0 taken 9101 times.
✓ Branch 1 taken 523891 times.
532994 if (is_update_query(prelocking_ctx->sql_command)) return TL_READ_NO_INSERT;
4434
4435 /*
4436 table_list is placeholder for prelocking.
4437 Ignore prelocking_placeholder status for non "LOCK TABLE" statement's
4438 table_list objects when routine_modifies_data is false.
4439 */
4440
4/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 523842 times.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 23 times.
523891 if (table_list->prelocking_placeholder &&
4441
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 25 times.
26 (routine_modifies_data || thd->in_lock_tables))
4442 24 return TL_READ_NO_INSERT;
4443
4444
2/2
✓ Branch 0 taken 5084 times.
✓ Branch 1 taken 518783 times.
523867 if (thd->locked_tables_mode > LTM_LOCK_TABLES) return TL_READ_NO_INSERT;
4445
4446 518783 return TL_READ;
4447 }
4448
4449 /**
4450 Process table's foreign keys (if any) by prelocking algorithm.
4451
4452 @param thd Thread context.
4453 @param prelocking_ctx Prelocking context of the statement.
4454 @param share Table's share.
4455 @param is_insert Indicates whether statement is going to INSERT
4456 into the table.
4457 @param is_update Indicates whether statement is going to UPDATE
4458 the table.
4459 @param is_delete Indicates whether statement is going to DELETE
4460 from the table.
4461 @param belong_to_view Uppermost view which uses this table element
4462 (nullptr - if it is not used by a view).
4463 @param[out] need_prelocking Set to true if method detects that prelocking
4464 required, not changed otherwise.
4465 */
4466 14589827 static void process_table_fks(THD *thd, Query_tables_list *prelocking_ctx,
4467 TABLE_SHARE *share, bool is_insert,
4468 bool is_update, bool is_delete,
4469 TABLE_LIST *belong_to_view,
4470 bool *need_prelocking) {
4471
4/4
✓ Branch 0 taken 12317252 times.
✓ Branch 1 taken 2272575 times.
✓ Branch 2 taken 12316810 times.
✓ Branch 3 taken 442 times.
14589827 if (!share->foreign_keys && !share->foreign_key_parents) {
4472 /*
4473 This table doesn't participate in any foreign keys, so nothing to
4474 process.
4475 */
4476 12316810 return;
4477 }
4478
4479 2273017 *need_prelocking = true;
4480
4481 /*
4482 In lower-case-table-names == 2 mode we store original versions of db
4483 and table names for tables participating in FK relationship, even
4484 though their comparison is performed in case insensitive fashion.
4485 Therefore we need to normalize/lowercase these names while prelocking
4486 set key is constructing from them.
4487 */
4488 2273017 bool normalize_db_names = (lower_case_table_names == 2);
4489 2273017 Sp_name_normalize_type name_normalize_type =
4490
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2273017 times.
2273017 (lower_case_table_names == 2) ? Sp_name_normalize_type::LOWERCASE_NAME
4491 : Sp_name_normalize_type::LEAVE_AS_IS;
4492
4493
3/4
✓ Branch 0 taken 643 times.
✓ Branch 1 taken 2272374 times.
✓ Branch 2 taken 703 times.
✗ Branch 3 not taken.
2273017 if (is_insert || is_update) {
4494 4546080 for (TABLE_SHARE_FOREIGN_KEY_INFO *fk = share->foreign_key;
4495
2/2
✓ Branch 0 taken 2273003 times.
✓ Branch 1 taken 2273077 times.
4546080 fk < share->foreign_key + share->foreign_keys; ++fk) {
4496 2273003 (void)sp_add_used_routine(
4497 prelocking_ctx, thd->stmt_arena,
4498 Sroutine_hash_entry::FK_TABLE_ROLE_PARENT_CHECK,
4499 fk->referenced_table_db.str, fk->referenced_table_db.length,
4500 fk->referenced_table_name.str, fk->referenced_table_name.length,
4501 normalize_db_names, name_normalize_type, false, belong_to_view);
4502 }
4503 }
4504
4505
4/4
✓ Branch 0 taken 2272928 times.
✓ Branch 1 taken 89 times.
✓ Branch 2 taken 2271704 times.
✓ Branch 3 taken 1224 times.
2273017 if (is_update || is_delete) {
4506 4543342 for (TABLE_SHARE_FOREIGN_KEY_PARENT_INFO *fk_p = share->foreign_key_parent;
4507
2/2
✓ Branch 0 taken 2271549 times.
✓ Branch 1 taken 2271793 times.
4543342 fk_p < share->foreign_key_parent + share->foreign_key_parents;
4508 ++fk_p) {
4509
2/2
✓ Branch 0 taken 238 times.
✓ Branch 1 taken 2271311 times.
2271549 if ((is_update &&
4510
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 94 times.
238 (fk_p->update_rule == dd::Foreign_key::RULE_NO_ACTION ||
4511
4/4
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 2271318 times.
✓ Branch 3 taken 132 times.
2271455 fk_p->update_rule == dd::Foreign_key::RULE_RESTRICT)) ||
4512 2271318 (is_delete &&
4513
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 2271226 times.
2271318 (fk_p->delete_rule == dd::Foreign_key::RULE_NO_ACTION ||
4514
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 74 times.
92 fk_p->delete_rule == dd::Foreign_key::RULE_RESTRICT))) {
4515 2271343 (void)sp_add_used_routine(
4516 prelocking_ctx, thd->stmt_arena,
4517 Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_CHECK,
4518 fk_p->referencing_table_db.str, fk_p->referencing_table_db.length,
4519 fk_p->referencing_table_name.str,
4520 fk_p->referencing_table_name.length, normalize_db_names,
4521 name_normalize_type, false, belong_to_view);
4522 }
4523
4524
2/2
✓ Branch 0 taken 238 times.
✓ Branch 1 taken 2271311 times.
2271549 if ((is_update &&
4525
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 124 times.
238 (fk_p->update_rule == dd::Foreign_key::RULE_CASCADE ||
4526
2/2
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 15 times.
114 fk_p->update_rule == dd::Foreign_key::RULE_SET_NULL ||
4527
3/4
✓ Branch 0 taken 99 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2271321 times.
✓ Branch 3 taken 89 times.
2271410 fk_p->update_rule == dd::Foreign_key::RULE_SET_DEFAULT)) ||
4528 2271321 (is_delete &&
4529
2/2
✓ Branch 0 taken 2271306 times.
✓ Branch 1 taken 15 times.
2271321 (fk_p->delete_rule == dd::Foreign_key::RULE_SET_NULL ||
4530
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2271306 times.
2271306 fk_p->delete_rule == dd::Foreign_key::RULE_SET_DEFAULT))) {
4531 154 (void)sp_add_used_routine(
4532 prelocking_ctx, thd->stmt_arena,
4533 Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_UPDATE,
4534 fk_p->referencing_table_db.str, fk_p->referencing_table_db.length,
4535 fk_p->referencing_table_name.str,
4536 fk_p->referencing_table_name.length, normalize_db_names,
4537 name_normalize_type, false, belong_to_view);
4538 }
4539
4540
4/4
✓ Branch 0 taken 2271328 times.
✓ Branch 1 taken 221 times.
✓ Branch 2 taken 63 times.
✓ Branch 3 taken 2271265 times.
2271549 if (is_delete && fk_p->delete_rule == dd::Foreign_key::RULE_CASCADE) {
4541 63 (void)sp_add_used_routine(
4542 prelocking_ctx, thd->stmt_arena,
4543 Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_DELETE,
4544 fk_p->referencing_table_db.str, fk_p->referencing_table_db.length,
4545 fk_p->referencing_table_name.str,
4546 fk_p->referencing_table_name.length, normalize_db_names,
4547 name_normalize_type, false, belong_to_view);
4548 }
4549 }
4550 }
4551 }
4552
4553 /**
4554 Handle element of prelocking set other than table. E.g. cache routine
4555 and, if prelocking strategy prescribes so, extend the prelocking set
4556 with tables and routines used by it.
4557
4558 @param[in] thd Thread context.
4559 @param[in] prelocking_ctx Prelocking context.
4560 @param[in] rt Element of prelocking set to be processed.
4561 @param[in] prelocking_strategy Strategy which specifies how the
4562 prelocking set should be extended when
4563 one of its elements is processed.
4564 @param[in] has_prelocking_list Indicates that prelocking set/list for
4565 this statement has already been built.
4566 @param[in] ot_ctx Context of open_table used to recover from
4567 locking failures.
4568 @param[out] need_prelocking Set to true if it was detected that this
4569 statement will require prelocked mode for
4570 its execution, not touched otherwise.
4571 @param[out] routine_modifies_data Set to true if it was detected that this
4572 routine does modify table data.
4573
4574 @retval false Success.
4575 @retval true Failure (Conflicting metadata lock, OOM, other errors).
4576 */
4577
4578 4881441 static bool open_and_process_routine(
4579 THD *thd, Query_tables_list *prelocking_ctx, Sroutine_hash_entry *rt,
4580 Prelocking_strategy *prelocking_strategy, bool has_prelocking_list,
4581 Open_table_context *ot_ctx, bool *need_prelocking,
4582 bool *routine_modifies_data) {
4583 4881441 *routine_modifies_data = false;
4584
1/2
✓ Branch 0 taken 4881441 times.
✗ Branch 1 not taken.
4881441 DBUG_TRACE;
4585
4586
3/4
✓ Branch 0 taken 313679 times.
✓ Branch 1 taken 23245 times.
✓ Branch 2 taken 4544517 times.
✗ Branch 3 not taken.
4881441 switch (rt->type()) {
4587 313679 case Sroutine_hash_entry::FUNCTION:
4588 case Sroutine_hash_entry::PROCEDURE: {
4589 sp_head *sp;
4590 /*
4591 Try to get MDL lock on the routine.
4592 Note that we do not take locks on top-level CALLs as this can
4593 lead to a deadlock. Not locking top-level CALLs does not break
4594 the binlog as only the statements in the called procedure show
4595 up there, not the CALL itself.
4596 */
4597
6/6
✓ Branch 0 taken 233742 times.
✓ Branch 1 taken 79937 times.
✓ Branch 2 taken 64458 times.
✓ Branch 3 taken 169284 times.
✓ Branch 4 taken 144395 times.
✓ Branch 5 taken 169284 times.
547421 if (rt != prelocking_ctx->sroutines_list.first ||
4598 233742 rt->type() != Sroutine_hash_entry::PROCEDURE) {
4599 144395 MDL_request mdl_request;
4600 144395 MDL_key mdl_key;
4601
4602
2/2
✓ Branch 0 taken 144052 times.
✓ Branch 1 taken 343 times.
144395 if (rt->type() == Sroutine_hash_entry::FUNCTION)
4603
4/8
✓ Branch 0 taken 144052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144052 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 144052 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 144052 times.
✗ Branch 7 not taken.
144052 dd::Function::create_mdl_key(rt->db(), rt->name(), &mdl_key);
4604 else
4605
4/8
✓ Branch 0 taken 343 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 343 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 343 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 343 times.
✗ Branch 7 not taken.
343 dd::Procedure::create_mdl_key(rt->db(), rt->name(), &mdl_key);
4606
4607
1/2
✓ Branch 0 taken 144395 times.
✗ Branch 1 not taken.
144395 MDL_REQUEST_INIT_BY_KEY(&mdl_request, &mdl_key, MDL_SHARED,
4608 MDL_TRANSACTION);
4609
4610 /*
4611 Waiting for a conflicting metadata lock to go away may
4612 lead to a deadlock, detected by MDL subsystem.
4613 If possible, we try to resolve such deadlocks by releasing all
4614 metadata locks and restarting the pre-locking process.
4615 To prevent the error from polluting the Diagnostics Area
4616 in case of successful resolution, install a special error
4617 handler for ER_LOCK_DEADLOCK error.
4618 */
4619 144395 MDL_deadlock_handler mdl_deadlock_handler(ot_ctx);
4620
4621
1/2
✓ Branch 0 taken 144395 times.
✗ Branch 1 not taken.
144395 thd->push_internal_handler(&mdl_deadlock_handler);
4622 bool result =
4623
1/2
✓ Branch 0 taken 144395 times.
✗ Branch 1 not taken.
144395 thd->mdl_context.acquire_lock(&mdl_request, ot_ctx->get_timeout());
4624
1/2
✓ Branch 0 taken 144395 times.
✗ Branch 1 not taken.
144395 thd->pop_internal_handler();
4625
4626
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 144394 times.
144395 if (result) return true;
4627
4628
3/4
✓ Branch 0 taken 130053 times.
✓ Branch 1 taken 14341 times.
✓ Branch 2 taken 130053 times.
✗ Branch 3 not taken.
144394 DEBUG_SYNC(thd, "after_shared_lock_pname");
4629
4630 /* Ensures the routine is up-to-date and cached, if exists. */
4631
3/4
✓ Branch 0 taken 144394 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 144393 times.
144394 if (sp_cache_routine(thd, rt, has_prelocking_list, &sp)) return true;
4632
4633 /* Remember the version of the routine in the parse tree. */
4634
3/4
✓ Branch 0 taken 144393 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
✓ Branch 3 taken 144362 times.
144393 if (check_and_update_routine_version(thd, rt, sp)) return true;
4635
4636 /* 'sp' is NULL when there is no such routine. */
4637
2/2
✓ Branch 0 taken 144272 times.
✓ Branch 1 taken 90 times.
144362 if (sp) {
4638 144272 *routine_modifies_data = sp->modifies_data();
4639
4640
2/2
✓ Branch 0 taken 143918 times.
✓ Branch 1 taken 354 times.
144272 if (!has_prelocking_list)
4641
1/2
✓ Branch 0 taken 143918 times.
✗ Branch 1 not taken.
143918 prelocking_strategy->handle_routine(thd, prelocking_ctx, rt, sp,
4642 need_prelocking);
4643 }
4644
2/2
✓ Branch 0 taken 144362 times.
✓ Branch 1 taken 33 times.
144395 } else {
4645 /*
4646 If it's a top level call, just make sure we have a recent
4647 version of the routine, if it exists.
4648 Validating routine version is unnecessary, since CALL
4649 does not affect the prepared statement prelocked list.
4650 */
4651
3/4
✓ Branch 0 taken 169283 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 169280 times.
169284 if (sp_cache_routine(thd, rt, false, &sp)) return true;
4652 }
4653 313642 } break;
4654 23245 case Sroutine_hash_entry::TRIGGER:
4655 /**
4656 We add trigger entries to lex->sroutines_list, but we don't
4657 load them here. The trigger entry is only used when building
4658 a transitive closure of objects used in a statement, to avoid
4659 adding to this closure objects that are used in the trigger more
4660 than once.
4661 E.g. if a trigger trg refers to table t2, and the trigger table t1
4662 is used multiple times in the statement (say, because it's used in
4663 function f1() twice), we will only add t2 once to the list of
4664 tables to prelock.
4665
4666 We don't take metadata locks on triggers either: they are protected
4667 by a respective lock on the table, on which the trigger is defined.
4668
4669 The only two cases which give "trouble" are SHOW CREATE TRIGGER
4670 and DROP TRIGGER statements. For these, statement syntax doesn't
4671 specify the table on which this trigger is defined, so we have
4672 to make a "dirty" read in the data dictionary to find out the
4673 table name. Once we discover the table name, we take a metadata
4674 lock on it, and this protects all trigger operations.
4675 Of course the table, in theory, may disappear between the dirty
4676 read and metadata lock acquisition, but in that case we just return
4677 a run-time error.
4678
4679 Grammar of other trigger DDL statements (CREATE, DROP) requires
4680 the table to be specified explicitly, so we use the table metadata
4681 lock to protect trigger metadata in these statements. Similarly, in
4682 DML we always use triggers together with their tables, and thus don't
4683 need to take separate metadata locks on them.
4684 */
4685 23245 break;
4686 4544517 case Sroutine_hash_entry::FK_TABLE_ROLE_PARENT_CHECK:
4687 case Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_CHECK:
4688 case Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_UPDATE:
4689 case Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_DELETE: {
4690
2/2
✓ Branch 0 taken 4544508 times.
✓ Branch 1 taken 9 times.
4544517 if (thd->locked_tables_mode == LTM_NONE) {
4691 4544508 MDL_request mdl_request;
4692
4693 /*
4694 Adjust metadata lock type according to the table's role in the
4695 FK relationship. Also acquire stronger locks when we are locking
4696 on behalf of LOCK TABLES.
4697 */
4698 enum_mdl_type mdl_lock_type;
4699 4544508 bool executing_LT = (prelocking_ctx->sql_command == SQLCOM_LOCK_TABLES);
4700
4701
6/6
✓ Branch 0 taken 2271542 times.
✓ Branch 1 taken 2272966 times.
✓ Branch 2 taken 2271339 times.
✓ Branch 3 taken 203 times.
✓ Branch 4 taken 4544305 times.
✓ Branch 5 taken 203 times.
6816050 if (rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_PARENT_CHECK ||
4702 2271542 rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_CHECK) {
4703 4544305 mdl_lock_type =
4704
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4544281 times.
4544305 (executing_LT ? MDL_SHARED_READ_ONLY : MDL_SHARED_READ);
4705 } else {
4706 203 mdl_lock_type =
4707
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 184 times.
203 (executing_LT ? MDL_SHARED_NO_READ_WRITE : MDL_SHARED_WRITE);
4708 }
4709
4710
1/2
✓ Branch 0 taken 4544508 times.
✗ Branch 1 not taken.
4544508 MDL_REQUEST_INIT_BY_PART_KEY(&mdl_request, MDL_key::TABLE,
4711 rt->part_mdl_key(),
4712 rt->part_mdl_key_length(), rt->db_length(),
4713 mdl_lock_type, MDL_TRANSACTION);
4714
4715 4544508 MDL_deadlock_handler mdl_deadlock_handler(ot_ctx);
4716
4717
1/2
✓ Branch 0 taken 4544508 times.
✗ Branch 1 not taken.
4544508 thd->push_internal_handler(&mdl_deadlock_handler);
4718 bool result =
4719
1/2
✓ Branch 0 taken 4544508 times.
✗ Branch 1 not taken.
4544508 thd->mdl_context.acquire_lock(&mdl_request, ot_ctx->get_timeout());
4720
1/2
✓ Branch 0 taken 4544508 times.
✗ Branch 1 not taken.
4544508 thd->pop_internal_handler();
4721
4722
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4544508 times.
4544508 if (result) return true;
4723
1/2
✓ Branch 0 taken 4544508 times.
✗ Branch 1 not taken.
4544508 } else {
4724 /*
4725 This function is called only if we are not in prelocked mode
4726 already. So we must be handling statement executed under
4727 LOCK TABLES in this case.
4728 */
4729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 assert(thd->locked_tables_mode == LTM_LOCK_TABLES);
4730
4731 /*
4732 Even though LOCK TABLES tries to automatically lock parent and child
4733 tables which might be necessary for foreign key checks/actions, there
4734 are some cases when we might miss them. So it is better to check that
4735 we have appropriate metadata lock explicitly and error out if not.
4736
4737 Some examples of problematic cases are:
4738
4739 *) We are executing DELETE FROM t1 under LOCK TABLES t1 READ
4740 and table t1 is a parent in a foreign key.
4741 In this case error about inappropriate lock on t1 will be
4742 reported at later stage than prelocking set is built.
4743 So we can't assume/assert that we have proper lock on the
4744 corresponding child table here.
4745
4746 *) Table t1 has a trigger, which contains DELETE FROM t2 and
4747 t2 is participating in FK as parent. In such situation
4748 LOCK TABLE t1 WRITE will lock t2 for write implicitly
4749 so both updates and delete on t2 will be allowed. However,
4750 t3 will be locked only in a way as if only deletes from
4751 t2 were allowed.
4752
4753 *) Prelocking list has been built earlier. Both child and parent
4754 definitions might have changed since this time so at LOCK TABLES
4755 time FK which corresponds to this element of prelocked set
4756 might be no longer around. In theory, we might be processing
4757 statement which is not marked as requiring prelocked set invalidation
4758 (and thus ignoring table version mismatches) or tables might be missing
4759 and this error can be suppressed. In such case we might not have
4760 appropriate metadata lock on our child/parent table.
4761 */
4762
6/6
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 1 times.
13 if (rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_PARENT_CHECK ||
4763 4 rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_CHECK) {
4764
3/6
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 8 times.
8 if (!thd->mdl_context.owns_equal_or_stronger_lock(
4765 MDL_key::TABLE, rt->db(), rt->name(), MDL_SHARED_READ_ONLY)) {
4766 my_error(ER_TABLE_NOT_LOCKED, MYF(0), rt->name());
4767 return true;
4768 }
4769 } else {
4770
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
1 if (!thd->mdl_context.owns_equal_or_stronger_lock(
4771 MDL_key::TABLE, rt->db(), rt->name(),
4772 MDL_SHARED_NO_READ_WRITE)) {
4773 my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), rt->name());
4774 return true;
4775 }
4776 }
4777 }
4778
4779
6/6
✓ Branch 0 taken 4544362 times.
✓ Branch 1 taken 155 times.
✓ Branch 2 taken 49 times.
✓ Branch 3 taken 4544313 times.
✓ Branch 4 taken 204 times.
✓ Branch 5 taken 4544313 times.
9088879 if (rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_UPDATE ||
4780 4544362 rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_DELETE) {
4781 /*
4782 In order to continue building prelocked set or validating
4783 prelocked set which already has been built we need to get
4784 access to table's TABLE_SHARE.
4785
4786 Getting unused TABLE object is more scalable that going
4787 directly for the TABLE_SHARE. If there are no unused TABLE
4788 object we might get at least pointer to the TABLE_SHARE
4789 from the table cache.
4790
4791 Note that under LOCK TABLES we can't rely on that table is
4792 going to be in THD::open_tables list, as LOCK TABLES only
4793 pre-acquires metadata locks on FK tables but doesn't
4794 pre-open them.
4795
4796 TODO: Perhaps we should give it a try as it can be more
4797 scalability friendly.
4798 */
4799 204 Table_cache *tc = table_cache_manager.get_cache(thd);
4800 TABLE *table;
4801 TABLE_SHARE *share;
4802
4803
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 tc->lock();
4804
4805
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 table = tc->get_table(thd, rt->part_mdl_key(),
4806 rt->part_mdl_key_length(), &share);
4807
4808
2/2
✓ Branch 0 taken 146 times.
✓ Branch 1 taken 58 times.
204 if (table) {
4809
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 146 times.
146 assert(table->s == share);
4810 /*
4811 Don't check if TABLE_SHARE::version matches version of tables
4812 previously opened by this statement. It might be problematic
4813 under LOCK TABLES and possible version difference can't affect
4814 FK-related part of prelocking set.
4815 */
4816
1/2
✓ Branch 0 taken 146 times.
✗ Branch 1 not taken.
146 tc->unlock();
4817
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 41 times.
58 } else if (share) {
4818 /*
4819 TODO: If we constantly hit this case it would harm scalability...
4820 Perhaps we need to create new unused TABLE instance in this
4821 case.
4822 */
4823
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 mysql_mutex_lock(&LOCK_open);
4824
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 tc->unlock();
4825
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 share->increment_ref_count();
4826
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 mysql_mutex_unlock(&LOCK_open);
4827
4828 /*
4829 Again, when building part of prelocking set related to foreign keys
4830 we can ignore fact that TABLE_SHARE::version is old.
4831 */
4832 } else {
4833
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 tc->unlock();
4834
4835 /*
4836 If we are validating existing prelocking set then the table
4837 might have been dropped. We suppress this error in this case.
4838 Prelocking set will be either invalidated, or error will be
4839 reported the parent table is accessed.
4840
4841 TODO: Perhaps we need to use get_table_share_with_discover()
4842 here but it gets complicated under LOCK TABLES.
4843 */
4844 41 No_such_table_error_handler no_such_table_handler;
4845
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 thd->push_internal_handler(&no_such_table_handler);
4846
4847
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 mysql_mutex_lock(&LOCK_open);
4848
2/4
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
✗ Branch 3 not taken.
41 share = get_table_share(thd, rt->db(), rt->name(), rt->part_mdl_key(),
4849 rt->part_mdl_key_length(), true);
4850
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 mysql_mutex_unlock(&LOCK_open);
4851
4852
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 thd->pop_internal_handler();
4853
4854
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 41 times.
41 if (!share && no_such_table_handler.safely_trapped_errors()) {
4855 break; // Jump out switch without error.
4856 }
4857
4858
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (!share) {
4859 return true;
4860 }
4861
4862
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (share->is_view) {
4863 /*
4864 Eeek! Somebody replaced the child table with a view. This can
4865 happen only when we are validating existing prelocked set.
4866 Parent either have been dropped or its definition has been
4867 changed. In either case our child table won't be accessed
4868 through the foreign key.
4869 */
4870 assert(has_prelocking_list);
4871
4872 mysql_mutex_lock(&LOCK_open);
4873 release_table_share(share);
4874 mysql_mutex_unlock(&LOCK_open);
4875
4876 if (ask_to_reprepare(thd)) return true;
4877
4878 break; // Jump out switch without error.
4879 }
4880
1/3
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
41 }
4881
4882 146 auto release_table_lambda = [thd](TABLE *tab) {
4883 146 release_or_close_table(thd, tab);
4884 350 };
4885 std::unique_ptr<TABLE, decltype(release_table_lambda)>
4886 204 release_table_guard(table, release_table_lambda);
4887
4888 /*
4889 We need to explicitly release TABLE_SHARE only if we don't
4890 have TABLE object.
4891 */
4892 58 auto release_share_lambda = [](TABLE_SHARE *tsh) {
4893 58 mysql_mutex_lock(&LOCK_open);
4894 58 release_table_share(tsh);
4895 58 mysql_mutex_unlock(&LOCK_open);
4896 58 };
4897 std::unique_ptr<TABLE_SHARE, decltype(release_share_lambda)>
4898 release_share_guard((table ? nullptr : share),
4899
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 146 times.
204 release_share_lambda);
4900
4901 /*
4902 We need to maintain versioning of the prelocked tables since this
4903 is needed for correct handling of prepared statements to catch
4904 situations where a prelocked table (which is added to the prelocked
4905 set during PREPARE) is changed between repeated executions of the
4906 prepared statement.
4907 */
4908
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 int64 share_version = share->get_table_ref_version();
4909
4910
2/2
✓ Branch 0 taken 202 times.
✓ Branch 1 taken 2 times.
204 if (rt->m_cache_version != share_version) {
4911 /*
4912 Version of the cached table share is different from the
4913 previous execution of the prepared statement, and it is
4914 unacceptable for this SQLCOM.
4915 */
4916
2/4
✓ Branch 0 taken 202 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 202 times.
202 if (ask_to_reprepare(thd)) return true;
4917 /* Always maintain the latest cache version. */
4918 202 rt->m_cache_version = share_version;
4919 }
4920
4921 /*
4922 If the child may be affected by update/delete and is in a read only
4923 schema, we must reject the statement.
4924 */
4925
3/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 188 times.
204 if (check_schema_readonly(thd, rt->db())) {
4926
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 my_error(ER_SCHEMA_READ_ONLY, MYF(0), rt->db());
4927 16 return true;
4928 }
4929
4930
2/2
✓ Branch 0 taken 186 times.
✓ Branch 1 taken 2 times.
188 if (!has_prelocking_list) {
4931 bool is_update =
4932 186 (rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_UPDATE);
4933 bool is_delete =
4934 186 (rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_DELETE);
4935
4936
1/2
✓ Branch 0 taken 186 times.
✗ Branch 1 not taken.
186 process_table_fks(thd, prelocking_ctx, share, false, is_update,
4937 is_delete, rt->belong_to_view, need_prelocking);
4938 }
4939
4/4
✓ Branch 0 taken 188 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 188 times.
✓ Branch 3 taken 16 times.
220 }
4940 4544501 } break;
4941 default:
4942 /* Impossible type value. */
4943 assert(0);
4944 }
4945 4881388 return false;
4946 4881440 }
4947
4948 /**
4949 Handle table list element by obtaining metadata lock, opening table or view
4950 and, if prelocking strategy prescribes so, extending the prelocking set with
4951 tables and routines used by it.
4952
4953 @param[in] thd Thread context.
4954 @param[in] lex LEX structure for statement.
4955 @param[in] tables Table list element to be processed.
4956 @param[in,out] counter Number of tables which are open.
4957 @param[in] prelocking_strategy Strategy which specifies how the
4958 prelocking set should be extended
4959 when table or view is processed.
4960 @param[in] has_prelocking_list Indicates that prelocking set/list for
4961 this statement has already been built.
4962 @param[in] ot_ctx Context used to recover from a failed
4963 open_table() attempt.
4964
4965 @retval false Success.
4966 @retval true Error, reported unless there is a chance to recover from it.
4967 */
4968
4969 119583062 static bool open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *const tables,
4970 uint *counter,
4971 Prelocking_strategy *prelocking_strategy,
4972 bool has_prelocking_list,
4973 Open_table_context *ot_ctx) {
4974 119583062 bool error = false;
4975 119583062 bool safe_to_ignore_table = false;
4976
1/2
✓ Branch 0 taken 119584044 times.
✗ Branch 1 not taken.
119583062 DBUG_TRACE;
4977
3/4
✓ Branch 0 taken 108898387 times.
✓ Branch 1 taken 10685536 times.
✓ Branch 2 taken 108898629 times.
✗ Branch 3 not taken.
119584044 DEBUG_SYNC(thd, "open_and_process_table");
4978
4979 /*
4980 Ignore placeholders for unnamed derived tables, as they are fully resolved
4981 by the optimizer.
4982 */
4983
8/8
✓ Branch 0 taken 119260305 times.
✓ Branch 1 taken 323682 times.
✓ Branch 2 taken 119253546 times.
✓ Branch 3 taken 6695 times.
✓ Branch 4 taken 50 times.
✓ Branch 5 taken 119253532 times.
✓ Branch 6 taken 330427 times.
✓ Branch 7 taken 119253532 times.
238837747 if (tables->is_derived() || tables->is_table_function() ||
4984 119253546 tables->is_recursive_reference())
4985 330427 goto end;
4986
4987
2/2
✓ Branch 0 taken 113 times.
✓ Branch 1 taken 119253049 times.
119253532 assert(!tables->common_table_expr());
4988
4989 /*
4990 If this TABLE_LIST object is a placeholder for an information_schema
4991 table, create a temporary table to represent the information_schema
4992 table in the query. Do not fill it yet - will be filled during
4993 execution.
4994 */
4995
2/2
✓ Branch 0 taken 316997 times.
✓ Branch 1 taken 118936052 times.
119253049 if (tables->schema_table) {
4996 /*
4997 Since we no longer set TABLE_LIST::schema_table/table for table
4998 list elements representing mergeable view, we can't meet a table
4999 list element which represent information_schema table and a view
5000 at the same time. Otherwise, acquiring metadata lock om the view
5001 would have been necessary.
5002 */
5003
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 316997 times.
316997 assert(!tables->is_view());
5004
5005
3/6
✓ Branch 0 taken 316997 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 316997 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 316997 times.
✗ Branch 5 not taken.
633994 if (!mysql_schema_table(thd, lex, tables) &&
5006
2/4
✓ Branch 0 taken 316997 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 316997 times.
✗ Branch 3 not taken.
316997 !check_and_update_table_version(thd, tables, tables->table->s)) {
5007 316997 goto end;
5008 }
5009 error = true;
5010 goto end;
5011 }
5012
5/8
✓ Branch 0 taken 118936548 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 118936573 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6134 times.
✓ Branch 5 taken 118930439 times.
✓ Branch 6 taken 5606 times.
✗ Branch 7 not taken.
118936052 DBUG_PRINT("tcache", ("opening table: '%s'.'%s' item: %p", tables->db,
5013 tables->table_name, tables));
5014
5015 118935997 (*counter)++;
5016
5017 /*
5018 Not a placeholder so this must be a base/temporary table or view.
5019 Open it:
5020 */
5021
5022 /*
5023 A TABLE_LIST object may have an associated open TABLE object
5024 (TABLE_LIST::table is not NULL) if it represents a pre-opened temporary
5025 table, or is a materialized view. (Derived tables are not handled here).
5026 */
5027
5028
6/8
✓ Branch 0 taken 253371 times.
✓ Branch 1 taken 118682626 times.
✓ Branch 2 taken 105 times.
✓ Branch 3 taken 253266 times.
✓ Branch 4 taken 105 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 105 times.
✗ Branch 7 not taken.
118935997 assert(tables->table == nullptr || is_temporary_table(tables) ||
5029 (tables->is_view() && tables->uses_materialization()));
5030
5031 /*
5032 OT_TEMPORARY_ONLY means that we are in CREATE TEMPORARY TABLE statement.
5033 Also such table list element can't correspond to prelocking placeholder
5034 or to underlying table of merge table.
5035 So existing temporary table should have been preopened by this moment
5036 and we can simply continue without trying to open temporary or base table.
5037 */
5038
6/8
✓ Branch 0 taken 51558 times.
✓ Branch 1 taken 118884439 times.
✓ Branch 2 taken 51558 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 51558 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 51557 times.
✓ Branch 7 taken 1 times.
118935997 assert(tables->open_type != OT_TEMPORARY_ONLY ||
5039 (tables->open_strategy && !tables->prelocking_placeholder &&
5040 tables->parent_l == nullptr));
5041
5042
6/6
✓ Branch 0 taken 118884419 times.
✓ Branch 1 taken 51577 times.
✓ Branch 2 taken 253135 times.
✓ Branch 3 taken 118631850 times.
✓ Branch 4 taken 118631812 times.
✓ Branch 5 taken 304750 times.
118935996 if (tables->open_type == OT_TEMPORARY_ONLY || is_temporary_table(tables)) {
5043 // Already "open", no action required
5044
2/2
✓ Branch 0 taken 43935 times.
✓ Branch 1 taken 118587877 times.
118631812 } else if (tables->prelocking_placeholder) {
5045 /*
5046 For the tables added by the pre-locking code, attempt to open
5047 the table but fail silently if the table does not exist.
5048 The real failure will occur when/if a statement attempts to use
5049 that table.
5050 */
5051 43935 No_such_table_error_handler no_such_table_handler;
5052
1/2
✓ Branch 0 taken 43935 times.
✗ Branch 1 not taken.
43935 thd->push_internal_handler(&no_such_table_handler);
5053
5054 /*
5055 We're opening a table from the prelocking list.
5056
5057 Since this table list element might have been added after pre-opening
5058 of temporary tables we have to try to open temporary table for it.
5059
5060 We can't simply skip this table list element and postpone opening of
5061 temporary tabletill the execution of substatement for several reasons:
5062 - Temporary table can be a MERGE table with base underlying tables,
5063 so its underlying tables has to be properly open and locked at
5064 prelocking stage.
5065 - Temporary table can be a MERGE table and we might be in PREPARE
5066 phase for a prepared statement. In this case it is important to call
5067 HA_ATTACH_CHILDREN for all merge children.
5068 This is necessary because merge children remember "TABLE_SHARE ref type"
5069 and "TABLE_SHARE def version" in the HA_ATTACH_CHILDREN operation.
5070 If HA_ATTACH_CHILDREN is not called, these attributes are not set.
5071 Then, during the first EXECUTE, those attributes need to be updated.
5072 That would cause statement re-preparing (because changing those
5073 attributes during EXECUTE is caught by THD::m_reprepare_observers).
5074 The problem is that since those attributes are not set in merge
5075 children, another round of PREPARE will not help.
5076 */
5077
1/2
✓ Branch 0 taken 43935 times.
✗ Branch 1 not taken.
43935 error = open_temporary_table(thd, tables);
5078
5079
4/6
✓ Branch 0 taken 43935 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 43433 times.
✓ Branch 3 taken 502 times.
✓ Branch 4 taken 43433 times.
✗ Branch 5 not taken.
43935 if (!error && !tables->table) error = open_table(thd, tables, ot_ctx);
5080
5081
1/2
✓ Branch 0 taken 43935 times.
✗ Branch 1 not taken.
43935 thd->pop_internal_handler();
5082 43935 safe_to_ignore_table = no_such_table_handler.safely_trapped_errors();
5083
4/4
✓ Branch 0 taken 8025 times.
✓ Branch 1 taken 118579852 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8023 times.
118631812 } else if (tables->parent_l && (thd->open_options & HA_OPEN_FOR_REPAIR)) {
5084 /*
5085 Also fail silently for underlying tables of a MERGE table if this
5086 table is opened for CHECK/REPAIR TABLE statement. This is needed
5087 to provide complete list of problematic underlying tables in
5088 CHECK/REPAIR TABLE output.
5089 */
5090 2 Repair_mrg_table_error_handler repair_mrg_table_handler;
5091
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 thd->push_internal_handler(&repair_mrg_table_handler);
5092
5093
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 error = open_temporary_table(thd, tables);
5094
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if (!error && !tables->table) error = open_table(thd, tables, ot_ctx);
5095
5096
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 thd->pop_internal_handler();
5097 2 safe_to_ignore_table = repair_mrg_table_handler.safely_trapped_errors();
5098 2 } else {
5099
2/2
✓ Branch 0 taken 8023 times.
✓ Branch 1 taken 118579852 times.
118587875 if (tables->parent_l) {
5100 /*
5101 Even if we are opening table not from the prelocking list we
5102 still might need to look for a temporary table if this table
5103 list element corresponds to underlying table of a merge table.
5104 */
5105
1/2
✓ Branch 0 taken 8023 times.
✗ Branch 1 not taken.
8023 error = open_temporary_table(thd, tables);
5106 }
5107
5108
7/8
✓ Branch 0 taken 118587021 times.
✓ Branch 1 taken 854 times.
✓ Branch 2 taken 118566857 times.
✓ Branch 3 taken 20669 times.
✓ Branch 4 taken 118567073 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 118587735 times.
✓ Branch 7 taken 645 times.
118587875 if (!error && (tables->is_view() || tables->table == nullptr))
5109
1/2
✓ Branch 0 taken 118587661 times.
✗ Branch 1 not taken.
118587735 error = open_table(thd, tables, ot_ctx);
5110 }
5111
5112
2/2
✓ Branch 0 taken 10294 times.
✓ Branch 1 taken 118925911 times.
118936205 if (error) {
5113
6/6
✓ Branch 0 taken 10258 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 226 times.
✓ Branch 3 taken 10032 times.
✓ Branch 4 taken 226 times.
✓ Branch 5 taken 10068 times.
10294 if (!ot_ctx->can_recover_from_failed_open() && safe_to_ignore_table) {
5114
3/8
✓ Branch 0 taken 226 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 226 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 226 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
226 DBUG_PRINT("info", ("open_table: ignoring table '%s'.'%s'", tables->db,
5115 tables->alias));
5116 226 error = false;
5117 }
5118 10294 goto end;
5119 }
5120
5121 // Do specific processing for a view, and skip actions that apply to tables
5122
5123
2/2
✓ Branch 0 taken 585977 times.
✓ Branch 1 taken 118340178 times.
118925911 if (tables->is_view()) {
5124 // Views do not count as tables
5125 585977 (*counter)--;
5126
5127 /*
5128 tables->next_global list consists of two parts:
5129 1) Query tables and underlying tables of views.
5130 2) Tables used by all stored routines that this statement invokes on
5131 execution.
5132 We need to know where the bound between these two parts is. If we've
5133 just opened a view, which was the last table in part #1, and it
5134 has added its base tables after itself, adjust the boundary pointer
5135 accordingly.
5136 */
5137
4/4
✓ Branch 0 taken 15454 times.
✓ Branch 1 taken 570523 times.
✓ Branch 2 taken 15430 times.
✓ Branch 3 taken 570547 times.
601431 if (lex->query_tables_own_last == &(tables->next_global) &&
5138
2/2
✓ Branch 0 taken 15430 times.
✓ Branch 1 taken 24 times.
15454 tables->view_query()->query_tables)
5139 15430 lex->query_tables_own_last = tables->view_query()->query_tables_last;
5140 /*
5141 Let us free memory used by 'sroutines' hash here since we never
5142 call destructor for this LEX.
5143 */
5144 585977 tables->view_query()->sroutines.reset();
5145 585977 goto process_view_routines;
5146 }
5147
5148 /*
5149 Special types of open can succeed but still don't set
5150 TABLE_LIST::table to anything.
5151 */
5152
4/4
✓ Branch 0 taken 2285088 times.
✓ Branch 1 taken 116055090 times.
✓ Branch 2 taken 757521 times.
✓ Branch 3 taken 1527567 times.
118340178 if (tables->open_strategy && !tables->table) goto end;
5153
5154 /*
5155 If we are not already in prelocked mode and extended table list is not
5156 yet built we might have to build the prelocking set for this statement.
5157
5158 Since currently no prelocking strategy prescribes doing anything for
5159 tables which are only read, we do below checks only if table is going
5160 to be changed.
5161 */
5162
6/6
✓ Branch 0 taken 117541700 times.
✓ Branch 1 taken 40957 times.
✓ Branch 2 taken 117531444 times.
✓ Branch 3 taken 10256 times.
✓ Branch 4 taken 33447218 times.
✓ Branch 5 taken 84135284 times.
235113946 if (thd->locked_tables_mode <= LTM_LOCK_TABLES && !has_prelocking_list &&
5163
2/2
✓ Branch 0 taken 33447008 times.
✓ Branch 1 taken 84084281 times.
117531444 tables->lock_descriptor().type >= TL_WRITE_ALLOW_WRITE) {
5164 33447218 bool need_prelocking = false;
5165 33447218 TABLE_LIST **save_query_tables_last = lex->query_tables_last;
5166 /*
5167 Extend statement's table list and the prelocking set with
5168 tables and routines according to the current prelocking
5169 strategy.
5170
5171 For example, for DML statements we need to add tables and routines
5172 used by triggers which are going to be invoked for this element of
5173 table list and also add tables required for handling of foreign keys.
5174 */
5175 error =
5176
2/4
✓ Branch 0 taken 33447244 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33446629 times.
✗ Branch 3 not taken.
33447218 prelocking_strategy->handle_table(thd, lex, tables, &need_prelocking);
5177
5178
6/6
✓ Branch 0 taken 2314168 times.
✓ Branch 1 taken 31132461 times.
✓ Branch 2 taken 2311166 times.
✓ Branch 3 taken 3002 times.
✓ Branch 4 taken 2311166 times.
✓ Branch 5 taken 31135463 times.
33446629 if (need_prelocking && !lex->requires_prelocking())
5179 2311166 lex->mark_as_requiring_prelocking(save_query_tables_last);
5180
5181
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33446821 times.
33446821 if (error) goto end;
5182 }
5183
5184 /* Check and update metadata version of a base table. */
5185
1/2
✓ Branch 0 taken 117582288 times.
✗ Branch 1 not taken.
117582105 error = check_and_update_table_version(thd, tables, tables->table->s);
5186
2/2
✓ Branch 0 taken 18274 times.
✓ Branch 1 taken 117564014 times.
117582288 if (error) goto end;
5187 /*
5188 After opening a MERGE table add the children to the query list of
5189 tables, so that they are opened too.
5190 Note that placeholders don't have the handler open.
5191 */
5192 /* MERGE tables need to access parent and child TABLE_LISTs. */
5193
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117564014 times.
117564014 assert(tables->table->pos_in_table_list == tables);
5194 /* Non-MERGE tables ignore this call. */
5195
3/4
✓ Branch 0 taken 117384650 times.
✓ Branch 1 taken 179364 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 117564435 times.
234949085 if (tables->table->db_stat &&
5196
2/4
✓ Branch 0 taken 117385071 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 117385071 times.
117384650 tables->table->file->ha_extra(HA_EXTRA_ADD_CHILDREN_LIST)) {
5197 error = true;
5198 goto end;
5199 }
5200
5201 117564435 process_view_routines:
5202
6/8
✓ Branch 0 taken 585976 times.
✓ Branch 1 taken 117564626 times.
✓ Branch 2 taken 585873 times.
✓ Branch 3 taken 103 times.
✓ Branch 4 taken 585874 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 117564622 times.
118150412 assert((tables->is_view() &&
5203 (tables->uses_materialization() || tables->table == nullptr)) ||
5204 (!tables->is_view()));
5205
5206 /*
5207 Again we may need cache all routines used by this view and add
5208 tables used by them to table list.
5209 */
5210
6/6
✓ Branch 0 taken 585977 times.
✓ Branch 1 taken 117564585 times.
✓ Branch 2 taken 585843 times.
✓ Branch 3 taken 134 times.
✓ Branch 4 taken 117564765 times.
✓ Branch 5 taken 585797 times.
118736442 if (tables->is_view() && thd->locked_tables_mode <= LTM_LOCK_TABLES &&
5211
2/2
✓ Branch 0 taken 585797 times.
✓ Branch 1 taken 46 times.
585843 !has_prelocking_list) {
5212 585797 bool need_prelocking = false;
5213 585797 TABLE_LIST **save_query_tables_last = lex->query_tables_last;
5214
5215 error =
5216
2/4
✓ Branch 0 taken 585797 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 585797 times.
✗ Branch 3 not taken.
585797 prelocking_strategy->handle_view(thd, lex, tables, &need_prelocking);
5217
5218
6/6
✓ Branch 0 taken 42075 times.
✓ Branch 1 taken 543722 times.
✓ Branch 2 taken 40759 times.
✓ Branch 3 taken 1316 times.
✓ Branch 4 taken 40759 times.
✓ Branch 5 taken 545038 times.
585797 if (need_prelocking && !lex->requires_prelocking())
5219 40759 lex->mark_as_requiring_prelocking(save_query_tables_last);
5220
5221
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 585797 times.
585797 if (error) goto end;
5222 }
5223
5224 117564765 end:
5225 119584095 return error;
5226 119584075 }
5227
5228 namespace {
5229
5230 struct schema_hash {
5231 1149842 size_t operator()(const TABLE_LIST *table) const {
5232
1/2
✓ Branch 0 taken 1149844 times.
✗ Branch 1 not taken.
1149842 return std::hash<std::string>()(std::string(table->db, table->db_length));
5233 }
5234 };
5235
5236 struct schema_key_equal {
5237 58239 bool operator()(const TABLE_LIST *a, const TABLE_LIST *b) const {
5238
1/2
✓ Branch 0 taken 58239 times.
✗ Branch 1 not taken.
116478 return a->db_length == b->db_length &&
5239
1/2
✓ Branch 0 taken 58239 times.
✗ Branch 1 not taken.
116478 memcmp(a->db, b->db, a->db_length) == 0;
5240 }
5241 };
5242
5243 } // namespace
5244
5245 /**
5246 Run the server hook called "before_dml". This is a hook originated from
5247 replication that allow server plugins to execute code before any DML
5248 instruction is executed.
5249 In case of negative outcome, it will set my_error to
5250 ER_BEFORE_DML_VALIDATION_ERROR
5251
5252 @param thd Thread context
5253
5254 @return hook outcome
5255 @retval 0 Everything is fine
5256 @retval !=0 Error in the outcome of the hook.
5257 */
5258 14739591 int run_before_dml_hook(THD *thd) {
5259 14739591 int out_value = 0;
5260
5261
1/2
✓ Branch 0 taken 14739882 times.
✗ Branch 1 not taken.
14739591 TX_TRACKER_GET(tst);
5262
1/2
✓ Branch 0 taken 14740250 times.
✗ Branch 1 not taken.
14739882 tst->add_trx_state(thd, TX_STMT_DML);
5263
5264
4/6
✓ Branch 0 taken 14740155 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 174766 times.
✓ Branch 3 taken 14565389 times.
✓ Branch 4 taken 174934 times.
✗ Branch 5 not taken.
14740250 (void)RUN_HOOK(transaction, before_dml, (thd, out_value));
5265
5266
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 14740253 times.
14740323 if (out_value) {
5267
1/2
✓ Branch 0 taken 70 times.
✗ Branch 1 not taken.
70 tst->clear_trx_state(thd, TX_STMT_DML);
5268
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
70 my_error(ER_BEFORE_DML_VALIDATION_ERROR, MYF(0));
5269 }
5270
5271 14740229 return out_value;
5272 }
5273
5274 /**
5275 Check whether a table being opened is a temporary table.
5276
5277 @param table table being opened
5278
5279 @return true if a table is temporary table, else false
5280 */
5281
5282 117827599 static inline bool is_temporary_table_being_opened(const TABLE_LIST *table) {
5283
2/2
✓ Branch 0 taken 117725486 times.
✓ Branch 1 taken 102113 times.
235553564 return table->open_type == OT_TEMPORARY_ONLY ||
5284
4/4
✓ Branch 0 taken 115457609 times.
✓ Branch 1 taken 2267877 times.
✓ Branch 2 taken 344282 times.
✓ Branch 3 taken 115113806 times.
233183574 (table->open_type == OT_TEMPORARY_OR_BASE &&
5285 233285687 is_temporary_table(table));
5286 }
5287
5288 /**
5289 Acquire IX metadata locks on tablespace names used by LOCK
5290 TABLES or by a DDL statement.
5291
5292 @note That the tablespace MDL locks are taken only after locks
5293 on tables are acquired. So it is recommended to maintain this
5294 same lock order across the server. It is very easy to break the
5295 this lock order if we invoke acquire_locks() with list of MDL
5296 requests which contain both MDL_key::TABLE and
5297 MDL_key::TABLESPACE. We would end-up in deadlock then.
5298
5299 @param thd Thread context.
5300 @param tables_start Start of list of tables on which locks
5301 should be acquired.
5302 @param tables_end End of list of tables.
5303 @param lock_wait_timeout Seconds to wait before timeout.
5304 @param flags Bitmap of flags to modify how the
5305 tables will be open, see open_table()
5306 description for details.
5307
5308 @retval true Failure (e.g. connection was killed)
5309 @retval false Success.
5310 */
5311 60415550 bool get_and_lock_tablespace_names(THD *thd, TABLE_LIST *tables_start,
5312 TABLE_LIST *tables_end,
5313 ulong lock_wait_timeout, uint flags) {
5314 // If this is a DISCARD or IMPORT TABLESPACE command (indicated by
5315 // the THD:: tablespace_op flag), we skip this phase, because these
5316 // commands are only used for file-per-table tablespaces, which we
5317 // do not lock. We also skip this phase if we are within the
5318 // context of a FLUSH TABLE WITH READ LOCK or FLUSH TABLE FOR EXPORT
5319 // statement, indicated by the MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK flag.
5320
7/8
✓ Branch 0 taken 60415079 times.
✓ Branch 1 taken 471 times.
✓ Branch 2 taken 60414565 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1157 times.
✓ Branch 5 taken 60413408 times.
✓ Branch 6 taken 1783 times.
✓ Branch 7 taken 60413253 times.
60415550 if (flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK || thd_tablespace_op(thd))
5321 1783 return false;
5322
5323 // Add tablespace names used under partition/subpartition definitions.
5324
1/2
✓ Branch 0 taken 60414476 times.
✗ Branch 1 not taken.
60413253 Tablespace_hash_set tablespace_set(PSI_INSTRUMENT_ME);
5325 180571994 if ((thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
5326
5/6
✓ Branch 0 taken 59743059 times.
✓ Branch 1 taken 671417 times.
✓ Branch 2 taken 78042 times.
✓ Branch 3 taken 59665017 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 60414459 times.
61163918 thd->lex->sql_command == SQLCOM_ALTER_TABLE) &&
5327
2/4
✓ Branch 0 taken 749442 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 749442 times.
749459 fill_partition_tablespace_names(thd->work_part_info, &tablespace_set))
5328 return true;
5329
5330 // The first step is to loop over the tables, make sure we have
5331 // locked the names, and then get hold of the tablespace names from
5332 // the data dictionary.
5333 TABLE_LIST *table;
5334
4/4
✓ Branch 0 taken 116522551 times.
✓ Branch 1 taken 60413059 times.
✓ Branch 2 taken 116521474 times.
✓ Branch 3 taken 1077 times.
176935610 for (table = tables_start; table && table != tables_end;
5335 116521151 table = table->next_global) {
5336 // Consider only non-temporary tables. The if clauses below have the
5337 // following meaning:
5338 //
5339 // !MDL_SHARED_READ_ONLY Not a LOCK TABLE ... READ.
5340 // In that case, tables will not
5341 // be altered, created or dropped,
5342 // so no need to IX lock the
5343 // tablespace.
5344 // is_ddl_or...request() || ...FOR_CREATE Request for a strong DDL or
5345 // LOCK TABLES type lock, or a
5346 // table to be created.
5347 // !OT_TEMPORARY_ONLY Not a user defined tmp table.
5348 // !(OT_TEMPORARY_OR_BASE && is_temp...()) Not a pre-opened tmp table.
5349
2/2
✓ Branch 0 taken 115571162 times.
✓ Branch 1 taken 572941 times.
116144103 if (table->mdl_request.type != MDL_SHARED_READ_ONLY &&
5350 116143871 (table->mdl_request.is_ddl_or_lock_tables_lock_request() ||
5351
2/2
✓ Branch 0 taken 671610 times.
✓ Branch 1 taken 114899552 times.
115571162 table->open_strategy == TABLE_LIST::OPEN_FOR_CREATE) &&
5352
8/8
✓ Branch 0 taken 116143871 times.
✓ Branch 1 taken 377603 times.
✓ Branch 2 taken 1149439 times.
✓ Branch 3 taken 94977 times.
✓ Branch 4 taken 1129486 times.
✓ Branch 5 taken 19953 times.
✓ Branch 6 taken 1129486 times.
✓ Branch 7 taken 115392085 times.
232665577 !is_temporary_table_being_opened(table) && !table->is_system_view) {
5353 // We have basically three situations here:
5354 //
5355 // 1. Lock only the target tablespace name and tablespace
5356 // names that are used by partitions (e.g. CREATE TABLE
5357 // explicitly specifying the tablespace names).
5358 // 2. Lock only the existing tablespace name and tablespace
5359 // names that are used by partitions (e.g. ALTER TABLE t
5360 // ADD COLUMN ... where t is defined in some tablespace s.
5361 // 3. Lock both the target and the existing tablespace names
5362 // along with tablespace names used by partitions. (e.g.
5363 // ALTER TABLE t TABLESPACE s2, where t is defined in
5364 // some tablespace s)
5365
2/2
✓ Branch 0 taken 430047 times.
✓ Branch 1 taken 699439 times.
1129486 if (table->target_tablespace_name.length > 0) {
5366
2/4
✓ Branch 0 taken 430047 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 430047 times.
✗ Branch 3 not taken.
430047 tablespace_set.insert(table->target_tablespace_name.str);
5367 }
5368
5369 // No need to try this for tables to be created since they are not
5370 // yet present in the dictionary.
5371
2/2
✓ Branch 0 taken 508732 times.
✓ Branch 1 taken 620334 times.
1129066 if (table->open_strategy != TABLE_LIST::OPEN_FOR_CREATE) {
5372 // Assert that we have an MDL lock on the table name. Needed to read
5373 // the dictionary safely.
5374
2/4
✓ Branch 0 taken 508732 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 508732 times.
508732 assert(thd->mdl_context.owns_equal_or_stronger_lock(
5375 MDL_key::TABLE, table->db, table->table_name, MDL_SHARED));
5376
5377 /*
5378 Add names of tablespaces used by table or by its
5379 partitions/subpartitions. Lookup data dictionary to get
5380 the information.
5381 */
5382
2/4
✓ Branch 0 taken 508732 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 508732 times.
508732 if (dd::fill_table_and_parts_tablespace_names(
5383 thd, table->db, table->table_name, &tablespace_set))
5384 return true;
5385 }
5386 }
5387 } // End of for(;;)
5388
5389 /*
5390 After we have identified the tablespace names, we iterate
5391 over the names and acquire IX locks on each of them.
5392 */
5393
5394
2/2
✓ Branch 0 taken 5484 times.
✓ Branch 1 taken 60408652 times.
60414136 if (thd->lex->sql_command == SQLCOM_DROP_DB) {
5395 /*
5396 In case of DROP DATABASE we might have to lock many thousands of
5397 tablespaces in extreme cases. Ensure that we don't hold memory used
5398 by corresponding MDL_requests after locks have been acquired to
5399 reduce memory usage by DROP DATABASE in such cases.
5400 */
5401 5484 MEM_ROOT mdl_reqs_root(key_memory_rm_db_mdl_reqs_root, MEM_ROOT_BLOCK_SIZE);
5402
5403
2/4
✓ Branch 0 taken 5484 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5484 times.
5484 if (lock_tablespace_names(thd, &tablespace_set, lock_wait_timeout,
5404 &mdl_reqs_root))
5405 return true;
5406
1/2
✓ Branch 0 taken 5484 times.
✗ Branch 1 not taken.
5484 } else {
5407
3/4
✓ Branch 0 taken 60407716 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 60407715 times.
60408652 if (lock_tablespace_names(thd, &tablespace_set, lock_wait_timeout,
5408 thd->mem_root))
5409 1 return true;
5410 }
5411
5412 60413199 return false;
5413 60413200 }
5414
5415 /**
5416 Acquire "strong" (SRO, SNW, SNRW) metadata locks on tables used by
5417 LOCK TABLES or by a DDL statement.
5418
5419 Acquire lock "S" on table being created in CREATE TABLE statement.
5420
5421 @note Under LOCK TABLES, we can't take new locks, so use
5422 open_tables_check_upgradable_mdl() instead.
5423
5424 @param thd Thread context.
5425 @param tables_start Start of list of tables on which locks
5426 should be acquired.
5427 @param tables_end End of list of tables.
5428 @param lock_wait_timeout Seconds to wait before timeout.
5429 @param flags Bitmap of flags to modify how the tables will be
5430 open, see open_table() description for details.
5431 @param schema_reqs When non-nullptr, pointer to array in which
5432 pointers to MDL requests for acquired schema
5433 locks to be stored. It is guaranteed that
5434 each schema will be present in this array
5435 only once.
5436
5437 @retval false Success.
5438 @retval true Failure (e.g. connection was killed)
5439 */
5440 60414278 bool lock_table_names(THD *thd, TABLE_LIST *tables_start,
5441 TABLE_LIST *tables_end, ulong lock_wait_timeout,
5442 uint flags,
5443 Prealloced_array<MDL_request *, 1> *schema_reqs) {
5444
1/2
✓ Branch 0 taken 60414706 times.
✗ Branch 1 not taken.
60414278 MDL_request_list mdl_requests;
5445 TABLE_LIST *table;
5446 60414706 MDL_request global_request;
5447 60414706 MDL_request backup_lock_request;
5448 malloc_unordered_set<TABLE_LIST *, schema_hash, schema_key_equal> schema_set(
5449
1/2
✓ Branch 0 taken 60414652 times.
✗ Branch 1 not taken.
60414706 PSI_INSTRUMENT_ME);
5450 60414652 bool need_global_read_lock_protection = false;
5451 60414652 bool acquire_backup_lock = false;
5452 60414652 MDL_request percona_backup_request;
5453
5454 /*
5455 This function is not supposed to be used under LOCK TABLES normally.
5456 Instead open_tables_check_upgradable_mdl() or some other function
5457 checking if we have tables locked in proper mode should be used.
5458
5459 The exception to this rule is RENAME TABLES code which uses this call
5460 to "upgrade" metadata lock on tables renamed along with acquiring
5461 exclusive locks on target table names, after checking that tables
5462 renamed are properly locked.
5463 */
5464
3/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 60414624 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
60414652 assert(!thd->locked_tables_mode ||
5465 thd->lex->sql_command == SQLCOM_RENAME_TABLE);
5466
5467 // Phase 1: Iterate over tables, collect set of unique schema names, and
5468 // construct a list of requests for table MDL locks.
5469
4/4
✓ Branch 0 taken 116524315 times.
✓ Branch 1 taken 60413838 times.
✓ Branch 2 taken 116523276 times.
✓ Branch 3 taken 1039 times.
176938153 for (table = tables_start; table && table != tables_end;
5470 116523501 table = table->next_global) {
5471
2/2
✓ Branch 0 taken 350076 times.
✓ Branch 1 taken 116173612 times.
116523276 if (is_temporary_table_being_opened(table)) {
5472 350076 continue;
5473 }
5474
5475
4/4
✓ Branch 0 taken 115265233 times.
✓ Branch 1 taken 908211 times.
✓ Branch 2 taken 114644368 times.
✓ Branch 3 taken 1529076 times.
231438845 if (!table->mdl_request.is_ddl_or_lock_tables_lock_request() &&
5476
2/2
✓ Branch 0 taken 114644619 times.
✓ Branch 1 taken 620614 times.
115265233 table->open_strategy != TABLE_LIST::OPEN_FOR_CREATE) {
5477 114644368 continue;
5478 } else {
5479 /*
5480 MDL_request::is_ddl_or_lock_tables_lock_request() returns true for
5481 DDL and LOCK TABLES statements. Since there isn't a way on MDL API level
5482 to determine whether a lock being acquired is requested as part of
5483 handling the statement LOCK TABLES, such check will be done by comparing
5484 a value of lex->sql_command against the constant SQLCOM_LOCK_TABLES.
5485 Also we shouldn't acquire IX backup lock in case a table being opened
5486 with requested MDL_SHARED_READ_ONLY lock. For example, such use case
5487 takes place when FLUSH PRIVILEGES executed.
5488 */
5489
2/2
✓ Branch 0 taken 1525910 times.
✓ Branch 1 taken 3166 times.
1529076 if (thd->lex->sql_command != SQLCOM_LOCK_TABLES &&
5490
2/2
✓ Branch 0 taken 1148915 times.
✓ Branch 1 taken 376995 times.
1525910 table->mdl_request.type != MDL_SHARED_READ_ONLY)
5491 1148915 acquire_backup_lock = true;
5492 }
5493
5494
2/2
✓ Branch 0 taken 1150494 times.
✓ Branch 1 taken 378582 times.
1529076 if (table->mdl_request.type != MDL_SHARED_READ_ONLY) {
5495 /* Write lock on normal tables is not allowed in a read only transaction.
5496 */
5497
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1150493 times.
1150494 if (thd->tx_read_only) {
5498
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, MYF(0));
5499 1 return true;
5500 }
5501
5502
2/2
✓ Branch 0 taken 1149844 times.
✓ Branch 1 taken 649 times.
1150493 if (!(flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK)) {
5503
1/2
✓ Branch 0 taken 1149843 times.
✗ Branch 1 not taken.
1149844 schema_set.insert(table);
5504 }
5505 1150492 need_global_read_lock_protection = true;
5506 }
5507
5508
1/2
✓ Branch 0 taken 1529057 times.
✗ Branch 1 not taken.
1529074 mdl_requests.push_front(&table->mdl_request);
5509 }
5510
5511 // Phase 2: Iterate over the schema set, add an IX lock for each
5512 // schema name.
5513
6/6
✓ Branch 0 taken 60414194 times.
✓ Branch 1 taken 683 times.
✓ Branch 2 taken 1130386 times.
✓ Branch 3 taken 59283735 times.
✓ Branch 4 taken 1130388 times.
✓ Branch 5 taken 59284416 times.
60414877 if (!(flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK) && !mdl_requests.is_empty()) {
5514 /*
5515 Scoped locks: Take intention exclusive locks on all involved
5516 schemas.
5517 */
5518
2/2
✓ Branch 0 taken 1091603 times.
✓ Branch 1 taken 1130387 times.
2221992 for (const TABLE_LIST *table_l : schema_set) {
5519
1/2
✓ Branch 0 taken 1091604 times.
✗ Branch 1 not taken.
1091604 MDL_request *schema_request = new (thd->mem_root) MDL_request;
5520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1091602 times.
1091602 if (schema_request == nullptr) return true;
5521
1/2
✓ Branch 0 taken 1091605 times.
✗ Branch 1 not taken.
1091602 MDL_REQUEST_INIT(schema_request, MDL_key::SCHEMA, table_l->db, "",
5522 MDL_INTENTION_EXCLUSIVE, MDL_TRANSACTION);
5523
1/2
✓ Branch 0 taken 1091604 times.
✗ Branch 1 not taken.
1091605 mdl_requests.push_front(schema_request);
5524
3/4
✓ Branch 0 taken 32930 times.
✓ Branch 1 taken 1058674 times.
✓ Branch 2 taken 32930 times.
✗ Branch 3 not taken.
1091604 if (schema_reqs) schema_reqs->push_back(schema_request);
5525 }
5526
5527
2/2
✓ Branch 0 taken 1068164 times.
✓ Branch 1 taken 62223 times.
1130387 if (need_global_read_lock_protection) {
5528 /*
5529 Protect this statement against concurrent global read lock
5530 by acquiring global intention exclusive lock with statement
5531 duration.
5532 */
5533
3/4
✓ Branch 0 taken 1068163 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 1068131 times.
1068164 if (thd->global_read_lock.can_acquire_protection()) return true;
5534
1/2
✓ Branch 0 taken 1068132 times.
✗ Branch 1 not taken.
1068131 MDL_REQUEST_INIT(&global_request, MDL_key::GLOBAL, "", "",
5535 MDL_INTENTION_EXCLUSIVE, MDL_STATEMENT);
5536
1/2
✓ Branch 0 taken 1068132 times.
✗ Branch 1 not taken.
1068132 mdl_requests.push_front(&global_request);
5537
5538
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 1068018 times.
1068132 if (thd->backup_tables_lock.abort_if_acquired()) return true;
5539
1/2
✓ Branch 0 taken 1068018 times.
✗ Branch 1 not taken.
1068018 thd->backup_tables_lock.init_protection_request(&percona_backup_request,
5540 MDL_STATEMENT);
5541
1/2
✓ Branch 0 taken 1068019 times.
✗ Branch 1 not taken.
1068018 mdl_requests.push_front(&percona_backup_request);
5542 }
5543 }
5544
5545
2/2
✓ Branch 0 taken 1067245 times.
✓ Branch 1 taken 59347413 times.
60414658 if (acquire_backup_lock) {
5546
1/2
✓ Branch 0 taken 1067244 times.
✗ Branch 1 not taken.
1067245 MDL_REQUEST_INIT(&backup_lock_request, MDL_key::BACKUP_LOCK, "", "",
5547 MDL_INTENTION_EXCLUSIVE, MDL_TRANSACTION);
5548
1/2
✓ Branch 0 taken 1067244 times.
✗ Branch 1 not taken.
1067244 mdl_requests.push_front(&backup_lock_request);
5549 }
5550
5551 // Phase 3: Acquire the locks which have been requested so far.
5552
3/4
✓ Branch 0 taken 60414344 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 243 times.
✓ Branch 3 taken 60414101 times.
60414657 if (thd->mdl_context.acquire_locks(&mdl_requests, lock_wait_timeout))
5553 243 return true;
5554
5555 /*
5556 Now when we have protection against concurrent change of read_only
5557 option we can safely re-check its value. Skip the check for
5558 FLUSH TABLES ... WITH READ LOCK and FLUSH TABLES ... FOR EXPORT
5559 as they are not supposed to be affected by read_only modes.
5560 */
5561 61482536 if (need_global_read_lock_protection &&
5562
2/2
✓ Branch 0 taken 1067835 times.
✓ Branch 1 taken 592 times.
1068427 !(flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK) &&
5563
5/6
✓ Branch 0 taken 1068427 times.
✓ Branch 1 taken 59345674 times.
✓ Branch 2 taken 1067845 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 60414094 times.
62550381 !(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) &&
5564
3/4
✓ Branch 0 taken 1067853 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 1067838 times.
1067845 check_readonly(thd, true))
5565 15 return true;
5566
5567 // Check schema read only for all schemas.
5568
2/2
✓ Branch 0 taken 1091267 times.
✓ Branch 1 taken 60414670 times.
61505334 for (const TABLE_LIST *table_l : schema_set)
5569
3/4
✓ Branch 0 taken 1091291 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 1091240 times.
1091244 if (check_schema_readonly(thd, table_l->db)) return true;
5570
5571 /*
5572 Phase 4: Lock tablespace names. This cannot be done as part
5573 of the previous phases, because we need to read the
5574 dictionary to get hold of the tablespace name, and in order
5575 to do this, we must have acquired a lock on the table.
5576 */
5577
1/2
✓ Branch 0 taken 60414314 times.
✗ Branch 1 not taken.
60414670 return get_and_lock_tablespace_names(thd, tables_start, tables_end,
5578 60414314 lock_wait_timeout, flags);
5579 60414770 }
5580
5581 /**
5582 Check for upgradable (SNW, SNRW) metadata locks on tables to be opened
5583 for a DDL statement. Under LOCK TABLES, we can't take new locks, so we
5584 must check if appropriate locks were pre-acquired.
5585
5586 @param thd Thread context.
5587 @param tables_start Start of list of tables on which upgradable locks
5588 should be searched for.
5589 @param tables_end End of list of tables.
5590
5591 @retval false Success.
5592 @retval true Failure (e.g. connection was killed)
5593 */
5594
5595 691768 static bool open_tables_check_upgradable_mdl(THD *thd, TABLE_LIST *tables_start,
5596 TABLE_LIST *tables_end) {
5597 TABLE_LIST *table;
5598
5599
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 691768 times.
691768 assert(thd->locked_tables_mode);
5600
5601
3/4
✓ Branch 0 taken 59018 times.
✓ Branch 1 taken 691733 times.
✓ Branch 2 taken 59018 times.
✗ Branch 3 not taken.
750751 for (table = tables_start; table && table != tables_end;
5602 58983 table = table->next_global) {
5603
6/6
✓ Branch 0 taken 1305 times.
✓ Branch 1 taken 57713 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 1301 times.
✓ Branch 4 taken 57717 times.
✓ Branch 5 taken 1301 times.
60323 if (!table->mdl_request.is_ddl_or_lock_tables_lock_request() ||
5604 1305 is_temporary_table_being_opened(table)) {
5605 57717 continue;
5606 }
5607
5608
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1299 times.
1301 if (table->mdl_request.type == MDL_SHARED_READ_ONLY) {
5609
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!thd->mdl_context.owns_equal_or_stronger_lock(
5610 MDL_key::TABLE, table->db, table->table_name,
5611 MDL_SHARED_READ_ONLY)) {
5612 2 my_error(ER_TABLE_NOT_LOCKED, MYF(0), table->table_name);
5613 2 return true;
5614 }
5615 } else {
5616 /*
5617 We don't need to do anything about the found TABLE instance as it
5618 will be handled later in open_tables(), we only need to check that
5619 an upgradable lock is already acquired. When we enter LOCK TABLES
5620 mode, SNRW locks are acquired before all other locks. So if under
5621 LOCK TABLES we find that there is TABLE instance with upgradeable
5622 lock, all other instances of TABLE for the same table will have the
5623 same ticket.
5624
5625 Note that this works OK even for CREATE TABLE statements which
5626 request X type of metadata lock. This is because under LOCK TABLES
5627 such statements don't create the table but only check if it exists
5628 or, in most complex case, only insert into it.
5629 Thus SNRW lock should be enough.
5630
5631 Note that find_table_for_mdl_upgrade() will report an error if
5632 no suitable ticket is found.
5633 */
5634
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 1266 times.
1299 if (!find_table_for_mdl_upgrade(thd, table->db, table->table_name, false))
5635 33 return true;
5636 }
5637 }
5638
5639 691733 return false;
5640 }
5641
5642 /**
5643 Iterate along a list of tables and acquire BACKUP LOCK in shared mode
5644 in case a strong MDL request (DDL/LOCK TABLES-type) was specified
5645 for a table.
5646
5647 @param[in] thd Thread context.
5648 @param[in] tables_start Pointer to a start of a list of tables to iterate
5649 @param[in] tables_end Pointer to a end of a list of tables where to stop
5650
5651 @return false on success, true on error.
5652 */
5653
5654 691733 static bool acquire_backup_lock_in_lock_tables_mode(THD *thd,
5655 TABLE_LIST *tables_start,
5656 TABLE_LIST *tables_end) {
5657 TABLE_LIST *table;
5658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 691733 times.
691733 assert(thd->locked_tables_mode);
5659
5660
3/4
✓ Branch 0 taken 58971 times.
✓ Branch 1 taken 690479 times.
✓ Branch 2 taken 58971 times.
✗ Branch 3 not taken.
749450 for (table = tables_start; table && table != tables_end;
5661 57717 table = table->next_global) {
5662
2/2
✓ Branch 0 taken 1338 times.
✓ Branch 1 taken 57633 times.
58971 if (is_temporary_table_being_opened(table)) continue;
5663
5664
4/4
✓ Branch 0 taken 1254 times.
✓ Branch 1 taken 56379 times.
✓ Branch 2 taken 1254 times.
✓ Branch 3 taken 56379 times.
58887 if (table->mdl_request.is_ddl_or_lock_tables_lock_request() &&
5665
1/2
✓ Branch 0 taken 1254 times.
✗ Branch 1 not taken.
1254 table->mdl_request.type != MDL_SHARED_READ_ONLY)
5666 1254 return acquire_shared_backup_lock(thd, thd->variables.lock_wait_timeout);
5667 }
5668
5669 690479 return false;
5670 }
5671
5672 /**
5673 Check if this is a DD table used under a I_S view then request InnoDB to
5674 do non-locking reads on the table.
5675
5676 @param thd Thread
5677 @param[in] tl TABLE_LIST pointing to table being checked.
5678
5679 @return false on success, true on error.
5680 */
5681
5682 119539844 static bool set_non_locking_read_for_IS_view(THD *thd, TABLE_LIST *tl) {
5683 119539844 TABLE *tbl = tl->table;
5684
5685 // Not a system view.
5686
6/6
✓ Branch 0 taken 117876713 times.
✓ Branch 1 taken 1663131 times.
✓ Branch 2 taken 117872432 times.
✓ Branch 3 taken 4281 times.
✓ Branch 4 taken 2634549 times.
✓ Branch 5 taken 115237883 times.
119539844 if (!(tbl && tbl->file && tl->referencing_view &&
5687
2/2
✓ Branch 0 taken 262244 times.
✓ Branch 1 taken 2372305 times.
2634549 tl->referencing_view->is_system_view))
5688 117167539 return false;
5689
5690 // Allow I_S system views to be locked by LOCK TABLE command.
5691
3/4
✓ Branch 0 taken 2372047 times.
✓ Branch 1 taken 258 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2372305 times.
4744352 if (thd->lex->sql_command != SQLCOM_LOCK_TABLES &&
5692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2372047 times.
2372047 tl->lock_descriptor().type >= TL_READ_NO_INSERT) {
5693 my_error(ER_IS_QUERY_INVALID_CLAUSE, MYF(0), "FOR UPDATE");
5694 return true;
5695 }
5696
5697 /* Convey to InnoDB (the DD table's engine) to do non-locking reads.
5698
5699 It is assumed that all the tables used by I_S views are
5700 always a DD table. If this is not true, then we might
5701 need to invoke dd::Dictionary::is_dd_tablename() to make sure.
5702 */
5703
5704 /* Addition to the above upstream comment:
5705 Compression_dictionary table is dd::System_tables::Types::SYSTEM, so
5706 pushing HA_EXTRA_NO_READ_LOCKING down will cause the assert in ha_innodb.cc
5707 line c.a. 19297 (no_read_locking == true, is_dd_table == false).
5708 This is the logic in ha_innobase::external_lock introduced in 8.0.22.
5709 Below causes HA_EXTRA_NO_READ_LOCKING not to be pushed for SYSTEM tables
5710 and we have locking as before.
5711 */
5712
3/6
✓ Branch 0 taken 2372303 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2372300 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2372304 times.
✗ Branch 5 not taken.
2372305 bool is_dd_table = dd::get_dictionary()->is_dd_table_name(
5713 tl->get_db_name(), tl->get_table_name());
5714
5/6
✓ Branch 0 taken 2333636 times.
✓ Branch 1 taken 38670 times.
✓ Branch 2 taken 2331121 times.
✓ Branch 3 taken 2515 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2372301 times.
4703422 if (is_dd_table && tbl->db_stat &&
5715
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2331116 times.
2331121 tbl->file->ha_extra(HA_EXTRA_NO_READ_LOCKING)) {
5716 // Handler->ha_extra() for innodb does not fail ever as of now.
5717 // In case it is made to fail sometime later, we need to think
5718 // about the kind of error to be report to user.
5719 assert(0);
5720 return true;
5721 }
5722
5723 2372301 return false;
5724 }
5725
5726 // Check if given TABLE_LIST is a acl table and is being read and not
5727 121171826 bool is_acl_table_in_non_LTM(const TABLE_LIST *tl,
5728 enum enum_locked_tables_mode ltm) {
5729 121171826 TABLE *table = tl->table;
5730
5731 /**
5732 We ignore use of ACL table,
5733 - Under LOCK TABLE modes.
5734 - Under system view. E.g., I_S.ROLE_* uses CTE where they use
5735 TL_READ_DEFAULT for ACL tables. We ignore them.
5736 - If the TABLE_LIST is used by optimizer as placeholder.
5737 */
5738
2/2
✓ Branch 0 taken 118851041 times.
✓ Branch 1 taken 173130 times.
240195997 return (!tl->is_placeholder() && table->db_stat &&
5739
4/4
✓ Branch 0 taken 1639505 times.
✓ Branch 1 taken 117211536 times.
✓ Branch 2 taken 1639018 times.
✓ Branch 3 taken 487 times.
118851041 table->s->table_category == TABLE_CATEGORY_ACL_TABLE &&
5740
3/4
✓ Branch 0 taken 119024171 times.
✓ Branch 1 taken 2149187 times.
✓ Branch 2 taken 1639018 times.
✗ Branch 3 not taken.
240197529 ltm != LTM_LOCK_TABLES && ltm != LTM_PRELOCKED_UNDER_LOCK_TABLES);
5741 }
5742
5743 /**
5744 Check if this is a ACL table is requested for read and
5745 then request InnoDB to do non-locking reads on the
5746 table.
5747
5748 @param thd Thread
5749 @param[in] tl TABLE_LIST pointing to table being checked.
5750 @param[in] issue_warning If true, issue warning irrespective of
5751 isolation level.
5752
5753 @return false on success, true on error.
5754 */
5755
5756 119489076 static bool set_non_locking_read_for_ACL_table(THD *thd, TABLE_LIST *tl,
5757 const bool &issue_warning) {
5758 119489076 TABLE *tbl = tl->table;
5759
5760 /*
5761 Request InnoDB to skip SE row locks if:
5762 - We have a ACL table name.
5763 - Lock type is TL_READ_DEFAULT or
5764 - Lock type is TL_READ_HIGH_PRIORITY.
5765
5766 Note:
5767 - We do this for all isolation modes as InnoDB sometimes acquires row
5768 locks even for modes other than serializable, e.g. to ensure correct
5769 binlogging or just to play safe.
5770
5771 - Checking only for TL_READ_DEFAULT and TL_READ_HIGH_PRIORITY allows to
5772 filter out all special non-SELECT cases which require locking like
5773 ALTER TABLE, ACL DDL and so on
5774 */
5775
4/4
✓ Branch 0 taken 1237531 times.
✓ Branch 1 taken 118252630 times.
✓ Branch 2 taken 36196 times.
✓ Branch 3 taken 119453902 times.
120726544 if (is_acl_table_in_non_LTM(tl, thd->locked_tables_mode) &&
5776
2/2
✓ Branch 0 taken 1201402 times.
✓ Branch 1 taken 36129 times.
1237531 (tl->lock_descriptor().type == TL_READ_DEFAULT ||
5777
2/2
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 1201272 times.
1201402 tl->lock_descriptor().type == TL_READ_HIGH_PRIORITY)) {
5778
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36196 times.
36196 if (tbl->file->ha_extra(HA_EXTRA_NO_READ_LOCKING)) {
5779 /*
5780 Handler->ha_extra() for InnoDB does not fail ever as of now. In
5781 case it is made to fail sometime later, we need to think about the
5782 kind of error to be report to user.
5783 */
5784 assert(0);
5785 return true;
5786 }
5787
5788 /**
5789 Issue a warning when,
5790 - We are skipping the SE locks in serializable
5791 - We are skipping the SE locks for SELECT IN SHARE MODE in all
5792 isolation mode.
5793 - When ACL table is not used under I_S system view.
5794 */
5795
4/4
✓ Branch 0 taken 36029 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 31 times.
✓ Branch 3 taken 35998 times.
36196 if ((thd->tx_isolation == ISO_SERIALIZABLE || issue_warning) &&
5796
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 194 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
198 !(tl->referencing_view && tl->referencing_view->is_system_view))
5797 194 push_warning(thd, Sql_condition::SL_WARNING,
5798 WARN_UNSUPPORTED_ACL_TABLES_READ,
5799 ER_THD(thd, WARN_UNSUPPORTED_ACL_TABLES_READ));
5800 }
5801
5802 119490034 return false;
5803 }
5804
5805 /**
5806 Open all tables in list
5807
5808 @param[in] thd Thread context.
5809 @param[in,out] start List of tables to be open (it can be adjusted for
5810 statement that uses tables only implicitly, e.g.
5811 for "SELECT f1()").
5812 @param[out] counter Number of tables which were open.
5813 @param[in] flags Bitmap of flags to modify how the tables will be
5814 open, see open_table() description for details.
5815 @param[in] prelocking_strategy Strategy which specifies how prelocking
5816 algorithm should work for this statement.
5817
5818 @note
5819 Unless we are already in prelocked mode and prelocking strategy prescribes
5820 so this function will also precache all SP/SFs explicitly or implicitly
5821 (via views and triggers) used by the query and add tables needed for their
5822 execution to table list. Statement that uses SFs, invokes triggers or
5823 requires foreign key checks will be marked as requiring prelocking.
5824 Prelocked mode will be enabled for such query during lock_tables() call.
5825
5826 If query for which we are opening tables is already marked as requiring
5827 prelocking it won't do such precaching and will simply reuse table list
5828 which is already built.
5829
5830 @retval false Success.
5831 @retval true Error, reported.
5832 */
5833
5834 61056556 bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
5835 Prelocking_strategy *prelocking_strategy) {
5836 /*
5837 We use pointers to "next_global" member in the last processed TABLE_LIST
5838 element and to the "next" member in the last processed Sroutine_hash_entry
5839 element as iterators over, correspondingly, the table list and stored
5840 routines list which stay valid and allow to continue iteration when new
5841 elements are added to the tail of the lists.
5842 */
5843 TABLE_LIST **table_to_open;
5844 TABLE *old_table;
5845 Sroutine_hash_entry **sroutine_to_open;
5846 TABLE_LIST *tables;
5847
1/2
✓ Branch 0 taken 61057516 times.
✗ Branch 1 not taken.
61056556 Open_table_context ot_ctx(thd, flags);
5848 61057516 bool error = false;
5849 61057516 bool some_routine_modifies_data = false;
5850 bool has_prelocking_list;
5851
1/2
✓ Branch 0 taken 61057290 times.
✗ Branch 1 not taken.
61057516 DBUG_TRACE;
5852 61057290 bool audit_notified = false;
5853
5854 61057325 restart:
5855 /*
5856 Close HANDLER tables which are marked for flush or against which there
5857 are pending exclusive metadata locks. This is needed both in order to
5858 avoid deadlocks and to have a point during statement execution at
5859 which such HANDLERs are closed even if they don't create problems for
5860 the current session (i.e. to avoid having a DDL blocked by HANDLERs
5861 opened for a long time).
5862 */
5863
3/4
✓ Branch 0 taken 2885 times.
✓ Branch 1 taken 61054249 times.
✓ Branch 2 taken 2885 times.
✗ Branch 3 not taken.
61057325 if (!thd->handler_tables_hash.empty()) mysql_ha_flush(thd);
5864
5865 61057134 has_prelocking_list = thd->lex->requires_prelocking();
5866 61057166 table_to_open = start;
5867
2/2
✓ Branch 0 taken 41836306 times.
✓ Branch 1 taken 19220860 times.
61057166 old_table = *table_to_open ? (*table_to_open)->table : nullptr;
5868 61057166 sroutine_to_open = &thd->lex->sroutines_list.first;
5869 61057166 *counter = 0;
5870
5871
2/2
✓ Branch 0 taken 37962867 times.
✓ Branch 1 taken 23094299 times.
61057166 if (!(thd->state_flags & Open_tables_state::SYSTEM_TABLES))
5872
1/2
✓ Branch 0 taken 37962363 times.
✗ Branch 1 not taken.
37962867 THD_STAGE_INFO(thd, stage_opening_tables);
5873
5874 /*
5875 If we are executing LOCK TABLES statement or a DDL statement
5876 (in non-LOCK TABLES mode) we might have to acquire upgradable
5877 semi-exclusive metadata locks (SNW or SNRW) on some of the
5878 tables to be opened.
5879 When executing CREATE TABLE .. If NOT EXISTS .. SELECT, the
5880 table may not yet exist, in which case we acquire an exclusive
5881 lock.
5882 We acquire all such locks at once here as doing this in one
5883 by one fashion may lead to deadlocks or starvation. Later when
5884 we will be opening corresponding table pre-acquired metadata
5885 lock will be reused (thanks to the fact that in recursive case
5886 metadata locks are acquired without waiting).
5887 */
5888
2/2
✓ Branch 0 taken 60881696 times.
✓ Branch 1 taken 174966 times.
61056662 if (!(flags & (MYSQL_OPEN_HAS_MDL_LOCK | MYSQL_OPEN_FORCE_SHARED_MDL |
5889 MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL))) {
5890
2/2
✓ Branch 0 taken 691768 times.
✓ Branch 1 taken 60189928 times.
60881696 if (thd->locked_tables_mode) {
5891 /*
5892 Under LOCK TABLES, we can't acquire new locks, so we instead
5893 need to check if appropriate locks were pre-acquired.
5894 */
5895 691768 TABLE_LIST *end_table = thd->lex->first_not_own_table();
5896
5/6
✓ Branch 0 taken 691768 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 691733 times.
✓ Branch 3 taken 35 times.
✓ Branch 4 taken 35 times.
✓ Branch 5 taken 691733 times.
1383501 if (open_tables_check_upgradable_mdl(thd, *start, end_table) ||
5897
2/4
✓ Branch 0 taken 691733 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 691733 times.
691733 acquire_backup_lock_in_lock_tables_mode(thd, *start, end_table)) {
5898 35 error = true;
5899 35 goto err;
5900 }
5901 } else {
5902 TABLE_LIST *table;
5903
3/4
✓ Branch 0 taken 60190259 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 293 times.
✓ Branch 3 taken 60189966 times.
60189928 if (lock_table_names(thd, *start, thd->lex->first_not_own_table(),
5904 ot_ctx.get_timeout(), flags)) {
5905 293 error = true;
5906 293 goto err;
5907 }
5908
6/6
✓ Branch 0 taken 116219051 times.
✓ Branch 1 taken 60188730 times.
✓ Branch 2 taken 116217870 times.
✓ Branch 3 taken 1202 times.
✓ Branch 4 taken 116217905 times.
✓ Branch 5 taken 60189897 times.
176407781 for (table = *start; table && table != thd->lex->first_not_own_table();
5909 116217815 table = table->next_global) {
5910
4/4
✓ Branch 0 taken 115571031 times.
✓ Branch 1 taken 646784 times.
✓ Branch 2 taken 1318200 times.
✓ Branch 3 taken 114899615 times.
231788936 if (table->mdl_request.is_ddl_or_lock_tables_lock_request() ||
5911
2/2
✓ Branch 0 taken 671352 times.
✓ Branch 1 taken 114899679 times.
115571031 table->open_strategy == TABLE_LIST::OPEN_FOR_CREATE)
5912 1318200 table->mdl_request.ticket = nullptr;
5913 }
5914 }
5915 }
5916
5917 /*
5918 Perform steps of prelocking algorithm until there are unprocessed
5919 elements in prelocking list/set.
5920 */
5921
2/2
✓ Branch 0 taken 41863755 times.
✓ Branch 1 taken 61206614 times.
103070369 while (*table_to_open ||
5922
4/4
✓ Branch 0 taken 60541140 times.
✓ Branch 1 taken 665474 times.
✓ Branch 2 taken 177767 times.
✓ Branch 3 taken 60363373 times.
61206614 (thd->locked_tables_mode <= LTM_LOCK_TABLES && *sroutine_to_open)) {
5923 /*
5924 For every table in the list of tables to open, try to find or open
5925 a table.
5926 */
5927
2/2
✓ Branch 0 taken 119583096 times.
✓ Branch 1 taken 42014183 times.
161597279 for (tables = *table_to_open; tables;
5928 119555757 table_to_open = &tables->next_global, tables = tables->next_global) {
5929 119583096 old_table = (*table_to_open)->table;
5930
1/2
✓ Branch 0 taken 119584013 times.
✗ Branch 1 not taken.
119583096 error = open_and_process_table(thd, thd->lex, tables, counter,
5931 prelocking_strategy, has_prelocking_list,
5932 &ot_ctx);
5933
5934
2/2
✓ Branch 0 taken 28343 times.
✓ Branch 1 taken 119555670 times.
119584013 if (error) {
5935
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 28306 times.
28343 if (ot_ctx.can_recover_from_failed_open()) {
5936 /*
5937 We have met exclusive metadata lock or old version of table.
5938 Now we have to close all tables and release metadata locks.
5939 We also have to throw away set of prelocked tables (and thus
5940 close tables from this set that were open by now) since it
5941 is possible that one of tables which determined its content
5942 was changed.
5943
5944 Instead of implementing complex/non-robust logic mentioned
5945 above we simply close and then reopen all tables.
5946
5947 We have to save pointer to table list element for table which we
5948 have failed to open since closing tables can trigger removal of
5949 elements from the table list (if MERGE tables are involved),
5950 */
5951
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
37 close_tables_for_reopen(thd, start, ot_ctx.start_of_statement_svp());
5952
5953 /*
5954 Here we rely on the fact that 'tables' still points to the valid
5955 TABLE_LIST element. Although currently this assumption is valid
5956 it may change in future.
5957 */
5958
3/4
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 35 times.
36 if (ot_ctx.recover_from_failed_open()) goto err;
5959
5960 /* Re-open temporary tables after close_tables_for_reopen(). */
5961
2/4
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 35 times.
35 if (open_temporary_tables(thd, *start)) goto err;
5962
5963 35 error = false;
5964 35 goto restart;
5965 }
5966 28306 goto err;
5967 }
5968
5969
3/4
✓ Branch 0 taken 108872168 times.
✓ Branch 1 taken 10683067 times.
✓ Branch 2 taken 108872690 times.
✗ Branch 3 not taken.
119555670 DEBUG_SYNC(thd, "open_tables_after_open_and_process_table");
5970 }
5971
5972 /*
5973 Iterate through set of tables and generate table access audit events.
5974 */
5975
7/8
✓ Branch 0 taken 41986667 times.
✓ Branch 1 taken 27516 times.
✓ Branch 2 taken 41986323 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 41986310 times.
✓ Branch 6 taken 13 times.
✓ Branch 7 taken 42013826 times.
42014183 if (!audit_notified && mysql_audit_table_access_notify(thd, *start)) {
5976 13 error = true;
5977 13 goto err;
5978 }
5979
5980 /*
5981 Event is not generated in the next loop. It may contain duplicated
5982 table entries as well as new tables discovered for stored procedures.
5983 Events for these tables will be generated during the queries of these
5984 stored procedures.
5985 */
5986 42013826 audit_notified = true;
5987
5988 /*
5989 If we are not already in prelocked mode and extended table list is
5990 not yet built for our statement we need to cache routines it uses
5991 and build the prelocking list for it.
5992 If we are not in prelocked mode but have built the extended table
5993 list, we still need to call open_and_process_routine() to take
5994 MDL locks on the routines.
5995 */
5996
2/2
✓ Branch 0 taken 41973568 times.
✓ Branch 1 taken 40258 times.
42013826 if (thd->locked_tables_mode <= LTM_LOCK_TABLES) {
5997 bool routine_modifies_data;
5998 /*
5999 Process elements of the prelocking set which are present there
6000 since parsing stage or were added to it by invocations of
6001 Prelocking_strategy methods in the above loop over tables.
6002
6003 For example, if element is a routine, cache it and then,
6004 if prelocking strategy prescribes so, add tables it uses to the
6005 table list and routines it might invoke to the prelocking set.
6006 */
6007
2/2
✓ Branch 0 taken 4881441 times.
✓ Branch 1 taken 41973515 times.
46854956 for (Sroutine_hash_entry *rt = *sroutine_to_open; rt;
6008 4881388 sroutine_to_open = &rt->next, rt = rt->next) {
6009 4881441 bool need_prelocking = false;
6010 4881441 TABLE_LIST **save_query_tables_last = thd->lex->query_tables_last;
6011
6012
1/2
✓ Branch 0 taken 4881440 times.
✗ Branch 1 not taken.
4881441 error = open_and_process_routine(
6013
1/2
✓ Branch 0 taken 4881441 times.
✗ Branch 1 not taken.
4881441 thd, thd->lex, rt, prelocking_strategy, has_prelocking_list,
6014 &ot_ctx, &need_prelocking, &routine_modifies_data);
6015
6016
6/6
✓ Branch 0 taken 144100 times.
✓ Branch 1 taken 4737340 times.
✓ Branch 2 taken 24187 times.
✓ Branch 3 taken 119913 times.
✓ Branch 4 taken 24187 times.
✓ Branch 5 taken 4857253 times.
4881440 if (need_prelocking && !thd->lex->requires_prelocking())
6017 24187 thd->lex->mark_as_requiring_prelocking(save_query_tables_last);
6018
6019
4/4
✓ Branch 0 taken 144100 times.
✓ Branch 1 taken 4737340 times.
✓ Branch 2 taken 34692 times.
✓ Branch 3 taken 109408 times.
4881440 if (need_prelocking && !*start) *start = thd->lex->query_tables;
6020
6021
2/2
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 4881388 times.
4881440 if (error) {
6022
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
52 if (ot_ctx.can_recover_from_failed_open()) {
6023 close_tables_for_reopen(thd, start,
6024 ot_ctx.start_of_statement_svp());
6025
0/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52 if (ot_ctx.recover_from_failed_open()) goto err;
6026
6027 /* Re-open temporary tables after close_tables_for_reopen(). */
6028 if (open_temporary_tables(thd, *start)) goto err;
6029
6030 error = false;
6031 goto restart;
6032 }
6033 /*
6034 Serious error during reading stored routines from mysql.proc table.
6035 Something is wrong with the table or its contents, and an error has
6036 been emitted; we must abort.
6037 */
6038 52 goto err;
6039 }
6040
6041 // Remember if any of SF modifies data.
6042 4881388 some_routine_modifies_data |= routine_modifies_data;
6043 }
6044 }
6045 }
6046
6047 /* Accessing data in XA_IDLE or XA_PREPARED is not allowed. */
6048
4/4
✓ Branch 0 taken 41810541 times.
✓ Branch 1 taken 19218306 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 61027770 times.
102838327 if (*start &&
6049
2/4
✓ Branch 0 taken 41809983 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41810001 times.
✗ Branch 3 not taken.
41810541 (thd->get_transaction()->xid_state()->check_xa_idle_or_prepared(true) ||
6050
3/4
✓ Branch 0 taken 41809498 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
✓ Branch 3 taken 41809464 times.
41810001 thd->get_transaction()->xid_state()->xa_trans_rolled_back()))
6051 16 return true;
6052
6053 /*
6054 If some routine is modifying the table then the statement is not read only.
6055 If timer is enabled then resetting the timer in this case.
6056 */
6057
4/4
✓ Branch 0 taken 140 times.
✓ Branch 1 taken 61027630 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 139 times.
61027770 if (thd->timer && some_routine_modifies_data) {
6058
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 reset_statement_timer(thd);
6059
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 157 times.
✗ Branch 3 not taken.
1 push_warning(thd, Sql_condition::SL_NOTE, ER_NON_RO_SELECT_DISABLE_TIMER,
6060 ER_THD(thd, ER_NON_RO_SELECT_DISABLE_TIMER));
6061 }
6062
6063 /*
6064 After successful open of all tables, including MERGE parents and
6065 children, attach the children to their parents. At end of statement,
6066 the children are detached. Attaching and detaching are always done,
6067 even under LOCK TABLES.
6068
6069 We also convert all TL_WRITE_DEFAULT and TL_READ_DEFAULT locks to
6070 appropriate "real" lock types to be used for locking and to be passed
6071 to storage engine.
6072 */
6073
2/2
✓ Branch 0 taken 119540126 times.
✓ Branch 1 taken 61028692 times.
180568818 for (tables = *start; tables; tables = tables->next_global) {
6074 119540126 TABLE *tbl = tables->table;
6075
6076 /*
6077 NOTE: temporary merge tables should be processed here too, because
6078 a temporary merge table can be based on non-temporary tables.
6079 */
6080
6081 /* Schema tables may not have a TABLE object here. */
6082
6/6
✓ Branch 0 taken 117877108 times.
✓ Branch 1 taken 1663018 times.
✓ Branch 2 taken 117872657 times.
✓ Branch 3 taken 4451 times.
✓ Branch 4 taken 4056 times.
✓ Branch 5 taken 117868601 times.
119540126 if (tbl && tbl->file && tbl->file->ht->db_type == DB_TYPE_MRG_MYISAM) {
6083 /* MERGE tables need to access parent and child TABLE_LISTs. */
6084
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4056 times.
4056 assert(tbl->pos_in_table_list == tables);
6085
6/8
✓ Branch 0 taken 4056 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4056 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 4054 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 4054 times.
4056 if (tbl->db_stat && tbl->file->ha_extra(HA_EXTRA_ATTACH_CHILDREN)) {
6086 2 error = true;
6087 4 goto err;
6088 }
6089 }
6090
6091 /*
6092 Access to ACL table in a SELECT ... LOCK IN SHARE MODE are required
6093 to skip acquiring row locks. So, we use TL_READ_DEFAULT lock on ACL
6094 tables. This allows concurrent ACL DDL's.
6095
6096 Do not request SE to skip row lock if 'flags' has
6097 MYSQL_OPEN_FORCE_SHARED_MDL, which indicates that this is PREPARE
6098 phase. It is OK to do so since during this phase no rows will be read
6099 anyway. And by doing this we avoid generation of extra warnings.
6100 EXECUTION phase will request SE to skip row locks if necessary.
6101 */
6102 119540124 bool issue_warning_on_skipping_row_lock = false;
6103 119540124 if (tables->lock_descriptor().type == TL_READ_WITH_SHARED_LOCKS &&
6104
6/6
✓ Branch 0 taken 831 times.
✓ Branch 1 taken 119539697 times.
✓ Branch 2 taken 830 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 41 times.
✓ Branch 5 taken 119540487 times.
119541358 !(flags & MYSQL_OPEN_FORCE_SHARED_MDL) &&
6105
3/4
✓ Branch 0 taken 830 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
✓ Branch 3 taken 789 times.
830 is_acl_table_in_non_LTM(tables, thd->locked_tables_mode)) {
6106 41 tables->set_lock({TL_READ_DEFAULT, THR_DEFAULT});
6107 41 issue_warning_on_skipping_row_lock = true;
6108 }
6109
6110 /* Set appropriate TABLE::lock_type. */
6111
6/6
✓ Branch 0 taken 117876964 times.
✓ Branch 1 taken 1663564 times.
✓ Branch 2 taken 117838762 times.
✓ Branch 3 taken 38609 times.
✓ Branch 4 taken 117752963 times.
✓ Branch 5 taken 1787972 times.
237379290 if (tbl && tables->lock_descriptor().type != TL_UNLOCK &&
6112
2/2
✓ Branch 0 taken 117752987 times.
✓ Branch 1 taken 85775 times.
117838762 !thd->locked_tables_mode) {
6113
2/2
✓ Branch 0 taken 2984525 times.
✓ Branch 1 taken 114768431 times.
117752963 if (tables->lock_descriptor().type == TL_WRITE_DEFAULT)
6114 2984525 tbl->reginfo.lock_type = thd->update_lock_default;
6115
2/2
✓ Branch 0 taken 11818876 times.
✓ Branch 1 taken 102949541 times.
114768431 else if (tables->lock_descriptor().type == TL_WRITE_CONCURRENT_DEFAULT)
6116 11818876 tables->table->reginfo.lock_type = thd->insert_lock_default;
6117
2/2
✓ Branch 0 taken 4113648 times.
✓ Branch 1 taken 98835886 times.
102949541 else if (tables->lock_descriptor().type == TL_READ_DEFAULT)
6118
1/2
✓ Branch 0 taken 4113648 times.
✗ Branch 1 not taken.
4113648 tbl->reginfo.lock_type = read_lock_type_for_table(
6119
1/2
✓ Branch 0 taken 4113648 times.
✗ Branch 1 not taken.
4113648 thd, thd->lex, tables, some_routine_modifies_data);
6120 else
6121 98835886 tbl->reginfo.lock_type = tables->lock_descriptor().type;
6122 }
6123
6124 /*
6125 SELECT using a I_S system view with 'FOR UPDATE' and
6126 'LOCK IN SHARED MODE' clause is not allowed.
6127 */
6128
4/4
✓ Branch 0 taken 442327 times.
✓ Branch 1 taken 119098576 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 119540901 times.
119983230 if (tables->is_system_view &&
6129
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 442325 times.
442327 tables->lock_descriptor().type == TL_READ_WITH_SHARED_LOCKS) {
6130
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 my_error(ER_IS_QUERY_INVALID_CLAUSE, MYF(0), "LOCK IN SHARE MODE");
6131 2 error = true;
6132 2 goto err;
6133 }
6134
6135 // Setup lock type for DD tables used under I_S view.
6136
2/4
✓ Branch 0 taken 119539975 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 119539975 times.
119540901 if (set_non_locking_read_for_IS_view(thd, tables)) {
6137 error = true;
6138 goto err;
6139 }
6140
6141 /**
6142 Setup lock type for read requests for ACL table in SQL statements.
6143
6144 Do not request SE to skip row lock if 'flags' has
6145 MYSQL_OPEN_FORCE_SHARED_MDL, which indicates that this is PREPARE
6146 phase. It is OK to do so since during this phase no rows will be read
6147 anyway. And by doing this we avoid generation of extra warnings.
6148 EXECUTION phase will request SE to skip row locks if necessary.
6149 */
6150
3/4
✓ Branch 0 taken 119489158 times.
✓ Branch 1 taken 50817 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 119540891 times.
239030049 if (!(flags & MYSQL_OPEN_FORCE_SHARED_MDL) &&
6151
2/4
✓ Branch 0 taken 119490074 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 119490074 times.
119489158 set_non_locking_read_for_ACL_table(
6152 thd, tables, issue_warning_on_skipping_row_lock)) {
6153 error = true;
6154 goto err;
6155 }
6156
6157 } // End of for(;;)
6158
6159 61028692 err:
6160 // If a new TABLE was introduced, it's garbage, don't link to it:
6161
6/6
✓ Branch 0 taken 28704 times.
✓ Branch 1 taken 61028692 times.
✓ Branch 2 taken 28635 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 15932 times.
✓ Branch 5 taken 12703 times.
61057396 if (error && *table_to_open && old_table != (*table_to_open)->table) {
6162 15932 (*table_to_open)->table = nullptr;
6163 }
6164
5/8
✓ Branch 0 taken 61056625 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 61056989 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1394 times.
✓ Branch 5 taken 61055595 times.
✓ Branch 6 taken 1465 times.
✗ Branch 7 not taken.
61057396 DBUG_PRINT("open_tables", ("returning: %d", (int)error));
6165 61057072 return error;
6166 61057088 }
6167
6168 /**
6169 Defines how prelocking algorithm for DML statements should handle routines:
6170 - For CALL statements we do unrolling (i.e. open and lock tables for each
6171 sub-statement individually). So for such statements prelocking is enabled
6172 only if stored functions are used in parameter list and only for period
6173 during which we calculate values of parameters. Thus in this strategy we
6174 ignore procedure which is directly called by such statement and extend
6175 the prelocking set only with tables/functions used by SF called from the
6176 parameter list.
6177 - For any other statement any routine which is directly or indirectly called
6178 by statement is going to be executed in prelocked mode. So in this case we
6179 simply add all tables and routines used by it to the prelocking set.
6180
6181 @param[in] thd Thread context.
6182 @param[in] prelocking_ctx Prelocking context of the statement.
6183 @param[in] rt Prelocking set element describing routine.
6184 @param[in] sp Routine body.
6185 @param[out] need_prelocking Set to true if method detects that prelocking
6186 required, not changed otherwise.
6187
6188 @retval false Success.
6189 @retval true Failure (OOM).
6190 */
6191
6192 143914 bool DML_prelocking_strategy::handle_routine(THD *thd,
6193 Query_tables_list *prelocking_ctx,
6194 Sroutine_hash_entry *rt,
6195 sp_head *sp,
6196 bool *need_prelocking) {
6197 /*
6198 We assume that for any "CALL proc(...)" statement sroutines_list will
6199 have 'proc' as first element (it may have several, consider e.g.
6200 "proc(sp_func(...)))". This property is currently guaranteed by the
6201 parser.
6202 */
6203
6204
4/6
✓ Branch 0 taken 64096 times.
✓ Branch 1 taken 79818 times.
✓ Branch 2 taken 64096 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 143914 times.
✗ Branch 5 not taken.
208010 if (rt != prelocking_ctx->sroutines_list.first ||
6205 64096 rt->type() != Sroutine_hash_entry::PROCEDURE) {
6206 143914 *need_prelocking = true;
6207 143914 sp_update_stmt_used_routines(thd, prelocking_ctx, &sp->m_sroutines,
6208 rt->belong_to_view);
6209 143914 sp->add_used_tables_to_table_list(thd, &prelocking_ctx->query_tables_last,
6210 prelocking_ctx->sql_command,
6211 rt->belong_to_view);
6212 }
6213 143914 sp->propagate_attributes(prelocking_ctx);
6214 143914 return false;
6215 }
6216
6217 /**
6218 Defines how prelocking algorithm for DML statements should handle table list
6219 elements:
6220 - If table has triggers we should add all tables and routines
6221 used by them to the prelocking set.
6222 - If table participates in a foreign key we should add another
6223 table from it to the prelocking set with an appropriate metadata
6224 lock.
6225
6226 We do not need to acquire metadata locks on trigger names
6227 in DML statements, since all DDL statements
6228 that change trigger metadata always lock their
6229 subject tables.
6230
6231 @param[in] thd Thread context.
6232 @param[in] prelocking_ctx Prelocking context of the statement.
6233 @param[in] table_list Table list element for table.
6234 @param[out] need_prelocking Set to true if method detects that prelocking
6235 required, not changed otherwise.
6236
6237 @retval false Success.
6238 @retval true Failure (OOM).
6239 */
6240
6241 33445195 bool DML_prelocking_strategy::handle_table(THD *thd,
6242 Query_tables_list *prelocking_ctx,
6243 TABLE_LIST *table_list,
6244 bool *need_prelocking) {
6245 /* We rely on a caller to check that table is going to be changed. */
6246
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33446286 times.
33445195 assert(table_list->lock_descriptor().type >= TL_WRITE_ALLOW_WRITE);
6247
6248
2/2
✓ Branch 0 taken 14801673 times.
✓ Branch 1 taken 18644613 times.
33446286 if (table_list->trg_event_map) {
6249
2/2
✓ Branch 0 taken 41123 times.
✓ Branch 1 taken 14760550 times.
14801673 if (table_list->table->triggers) {
6250 41123 *need_prelocking = true;
6251
6252
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41123 times.
41123 if (table_list->table->triggers->add_tables_and_routines_for_triggers(
6253 thd, prelocking_ctx, table_list))
6254 return true;
6255 }
6256
6257 /*
6258 When FOREIGN_KEY_CHECKS is 0 we are not going to do any foreign key checks
6259 so we don't need to add child and parent tables to the prelocking list.
6260
6261 However, since trigger or stored function might change this variable for
6262 their duration (it is, actually, advisable to do so in some scenarios),
6263 we can apply this optimization only to tables which are directly used by
6264 the top-level statement.
6265
6266 While processing LOCK TABLES, we must disregard F_K_C too, since the
6267 prelocking set will be used while in LTM mode, and F_K_C may be turned
6268 on later, after the set has been established.
6269 */
6270
2/2
✓ Branch 0 taken 6747 times.
✓ Branch 1 taken 14794926 times.
14801673 if ((!(thd->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS) ||
6271
2/2
✓ Branch 0 taken 6197 times.
✓ Branch 1 taken 550 times.
6747 prelocking_ctx->sql_command == SQLCOM_LOCK_TABLES ||
6272
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 6168 times.
6197 table_list->prelocking_placeholder) &&
6273
2/2
✓ Branch 0 taken 14590580 times.
✓ Branch 1 taken 204925 times.
14795505 !(table_list->table->s->tmp_table)) {
6274 14590580 bool is_insert =
6275 14590580 (table_list->trg_event_map &
6276 static_cast<uint8>(1 << static_cast<int>(TRG_EVENT_INSERT)));
6277 14590580 bool is_update =
6278 14590580 (table_list->trg_event_map &
6279 static_cast<uint8>(1 << static_cast<int>(TRG_EVENT_UPDATE)));
6280 14590580 bool is_delete =
6281 14590580 (table_list->trg_event_map &
6282 static_cast<uint8>(1 << static_cast<int>(TRG_EVENT_DELETE)));
6283
6284 14590580 process_table_fks(thd, prelocking_ctx, table_list->table->s, is_insert,
6285 is_update, is_delete, table_list->belong_to_view,
6286 need_prelocking);
6287 }
6288 }
6289 33445384 return false;
6290 }
6291
6292 /**
6293 Defines how prelocking algorithm for DML statements should handle view -
6294 all view routines should be added to the prelocking set.
6295
6296 @param[in] thd Thread context.
6297 @param[in] prelocking_ctx Prelocking context of the statement.
6298 @param[in] table_list Table list element for view.
6299 @param[out] need_prelocking Set to true if method detects that prelocking
6300 required, not changed otherwise.
6301
6302 @retval false Success.
6303 @retval true Failure (OOM).
6304 */
6305
6306 585795 bool DML_prelocking_strategy::handle_view(THD *thd,
6307 Query_tables_list *prelocking_ctx,
6308 TABLE_LIST *table_list,
6309 bool *need_prelocking) {
6310
2/2
✓ Branch 0 taken 42075 times.
✓ Branch 1 taken 543721 times.
585795 if (table_list->view_query()->uses_stored_routines()) {
6311 42075 *need_prelocking = true;
6312
6313 84150 sp_update_stmt_used_routines(thd, prelocking_ctx,
6314 42075 &table_list->view_query()->sroutines_list,
6315 table_list->top_table());
6316 }
6317
6318 /*
6319 If a trigger was defined on one of the associated tables then assign the
6320 'trg_event_map' value of the view to the next table in table_list. When a
6321 Stored function is invoked, all the associated tables including the tables
6322 associated with the trigger are prelocked.
6323 */
6324
4/4
✓ Branch 0 taken 10606 times.
✓ Branch 1 taken 575190 times.
✓ Branch 2 taken 10586 times.
✓ Branch 3 taken 20 times.
585796 if (table_list->trg_event_map && table_list->next_global)
6325 10586 table_list->next_global->trg_event_map = table_list->trg_event_map;
6326 585796 return false;
6327 }
6328
6329 /**
6330 Defines how prelocking algorithm for LOCK TABLES statement should handle
6331 table list elements.
6332
6333 @param[in] thd Thread context.
6334 @param[in] prelocking_ctx Prelocking context of the statement.
6335 @param[in] table_list Table list element for table.
6336 @param[out] need_prelocking Set to true if method detects that prelocking
6337 required, not changed otherwise.
6338
6339 @retval false Success.
6340 @retval true Failure (OOM).
6341 */
6342
6343 1626 bool Lock_tables_prelocking_strategy::handle_table(
6344 THD *thd, Query_tables_list *prelocking_ctx, TABLE_LIST *table_list,
6345 bool *need_prelocking) {
6346
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1626 times.
1626 if (DML_prelocking_strategy::handle_table(thd, prelocking_ctx, table_list,
6347 need_prelocking))
6348 return true;
6349
6350 /* We rely on a caller to check that table is going to be changed. */
6351
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1626 times.
1626 assert(table_list->lock_descriptor().type >= TL_WRITE_ALLOW_WRITE);
6352
6353 1626 return false;
6354 }
6355
6356 /**
6357 Defines how prelocking algorithm for ALTER TABLE statement should handle
6358 routines - do nothing as this statement is not supposed to call routines.
6359
6360 We still can end up in this method when someone tries
6361 to define a foreign key referencing a view, and not just
6362 a simple view, but one that uses stored routines.
6363 */
6364
6365 4 bool Alter_table_prelocking_strategy::handle_routine(THD *, Query_tables_list *,
6366 Sroutine_hash_entry *,
6367 sp_head *, bool *) {
6368 4 return false;
6369 }
6370
6371 /**
6372 Defines how prelocking algorithm for ALTER TABLE statement should handle
6373 table list elements.
6374
6375 Unlike in DML, we do not process triggers here.
6376 */
6377
6378 1200 bool Alter_table_prelocking_strategy::handle_table(THD *, Query_tables_list *,
6379 TABLE_LIST *, bool *) {
6380 1200 return false;
6381 }
6382
6383 /**
6384 Defines how prelocking algorithm for ALTER TABLE statement
6385 should handle view - do nothing. We don't need to add view
6386 routines to the prelocking set in this case as view is not going
6387 to be materialized.
6388 */
6389
6390 1 bool Alter_table_prelocking_strategy::handle_view(THD *, Query_tables_list *,
6391 TABLE_LIST *, bool *) {
6392 1 return false;
6393 }
6394
6395 /**
6396 Check that lock is ok for tables; Call start stmt if ok
6397
6398 @param thd Thread handle.
6399 @param prelocking_ctx Prelocking context.
6400 @param table_list Table list element for table to be checked.
6401
6402 @retval false - Ok.
6403 @retval true - Error.
6404 */
6405
6406 2436219 static bool check_lock_and_start_stmt(THD *thd,
6407 Query_tables_list *prelocking_ctx,
6408 TABLE_LIST *table_list) {
6409 int error;
6410 thr_lock_type lock_type;
6411
1/2
✓ Branch 0 taken 2436219 times.
✗ Branch 1 not taken.
2436219 DBUG_TRACE;
6412
6413 /*
6414 Prelocking placeholder is not set for TABLE_LIST that
6415 are directly used by TOP level statement.
6416 */
6417
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2436219 times.
2436219 assert(table_list->prelocking_placeholder == false);
6418
6419 /*
6420 TL_WRITE_DEFAULT, TL_READ_DEFAULT and TL_WRITE_CONCURRENT_DEFAULT
6421 are supposed to be parser only types of locks so they should be
6422 converted to appropriate other types to be passed to storage engine.
6423 The exact lock type passed to the engine is important as, for example,
6424 InnoDB uses it to determine what kind of row locks should be acquired
6425 when executing statement in prelocked mode or under LOCK TABLES with
6426 @@innodb_table_locks = 0.
6427
6428 Last argument routine_modifies_data for read_lock_type_for_table()
6429 is ignored, as prelocking placeholder will never be set here.
6430 */
6431
2/2
✓ Branch 0 taken 2304859 times.
✓ Branch 1 taken 131360 times.
2436219 if (table_list->lock_descriptor().type == TL_WRITE_DEFAULT)
6432 2304859 lock_type = thd->update_lock_default;
6433
2/2
✓ Branch 0 taken 45901 times.
✓ Branch 1 taken 85459 times.
131360 else if (table_list->lock_descriptor().type == TL_WRITE_CONCURRENT_DEFAULT)
6434 45901 lock_type = thd->insert_lock_default;
6435
2/2
✓ Branch 0 taken 57722 times.
✓ Branch 1 taken 27737 times.
85459 else if (table_list->lock_descriptor().type == TL_READ_DEFAULT)
6436
1/2
✓ Branch 0 taken 57722 times.
✗ Branch 1 not taken.
57722 lock_type = read_lock_type_for_table(thd, prelocking_ctx, table_list, true);
6437 else
6438 27737 lock_type = table_list->lock_descriptor().type;
6439
6440
2/2
✓ Branch 0 taken 2350800 times.
✓ Branch 1 taken 85419 times.
2436219 if ((int)lock_type > (int)TL_WRITE_ALLOW_WRITE &&
6441
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 2350782 times.
2350800 (int)table_list->table->reginfo.lock_type <= (int)TL_WRITE_ALLOW_WRITE) {
6442
1/2
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
18 my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_list->alias);
6443 18 return true;
6444 }
6445
2/4
✓ Branch 0 taken 2436201 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2436201 times.
2436201 if ((error = table_list->table->file->start_stmt(thd, lock_type))) {
6446 table_list->table->file->print_error(error, MYF(0));
6447 return true;
6448 }
6449
6450 /*
6451 Record in transaction state tracking
6452 */
6453
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2436198 times.
2436201 if (thd->variables.session_track_transaction_info > TX_TRACK_NONE) {
6454
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 TX_TRACKER_GET(tst);
6455 enum enum_tx_state s;
6456
6457
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 s = tst->calc_trx_state(lock_type,
6458 3 table_list->table->file->has_transactions());
6459
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 tst->add_trx_state(thd, s);
6460 }
6461
6462 2436201 return false;
6463 2436219 }
6464
6465 /**
6466 @brief Open and lock one table
6467
6468 @param[in] thd thread handle
6469 @param[in] table_l table to open is first table in this list
6470 @param[in] lock_type lock to use for table
6471 @param[in] flags options to be used while opening and locking
6472 table (see open_table(), mysql_lock_tables())
6473 @param[in] prelocking_strategy Strategy which specifies how prelocking
6474 algorithm should work for this statement.
6475
6476 @return table
6477 @retval != NULL OK, opened table returned
6478 @retval NULL Error
6479
6480 @note
6481 If ok, the following are also set:
6482 table_list->lock_type lock_type
6483 table_list->table table
6484
6485 @note
6486 If table_l is a list, not a single table, the list is temporarily
6487 broken.
6488
6489 @details
6490 This function is meant as a replacement for open_ltable() when
6491 MERGE tables can be opened. open_ltable() cannot open MERGE tables.
6492
6493 There may be more differences between open_n_lock_single_table() and
6494 open_ltable(). One known difference is that open_ltable() does
6495 neither call thd->decide_logging_format() nor handle some other logging
6496 and locking issues because it does not call lock_tables().
6497 */
6498
6499 1297057 TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
6500 thr_lock_type lock_type, uint flags,
6501 Prelocking_strategy *prelocking_strategy) {
6502 TABLE_LIST *save_next_global;
6503
1/2
✓ Branch 0 taken 1297089 times.
✗ Branch 1 not taken.
1297057 DBUG_TRACE;
6504
6505 /* Remember old 'next' pointer. */
6506 1297089 save_next_global = table_l->next_global;
6507 /* Break list. */
6508 1297089 table_l->next_global = nullptr;
6509
6510 /* Set requested lock type. */
6511 1297089 table_l->set_lock({lock_type, THR_DEFAULT});
6512 /* Allow to open real tables only. */
6513 1297083 table_l->required_type = dd::enum_table_type::BASE_TABLE;
6514
6515 /* Open the table. */
6516
3/4
✓ Branch 0 taken 1296999 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 1296964 times.
1297083 if (open_and_lock_tables(thd, table_l, flags, prelocking_strategy))
6517 35 table_l->table = nullptr; /* Just to be sure. */
6518
6519 /* Restore list. */
6520 1296999 table_l->next_global = save_next_global;
6521
6522 1297088 return table_l->table;
6523 1296999 }
6524
6525 /*
6526 Open and lock one table
6527
6528 SYNOPSIS
6529 open_ltable()
6530 thd Thread handler
6531 table_list Table to open is first table in this list
6532 lock_type Lock to use for open
6533 lock_flags Flags passed to mysql_lock_table
6534
6535 NOTE
6536 This function doesn't do anything like SP/SF/views/triggers analysis done
6537 in open_table()/lock_tables(). It is intended for opening of only one
6538 concrete table. And used only in special contexts.
6539
6540 RETURN VALUES
6541 table Opened table
6542 0 Error
6543
6544 If ok, the following are also set:
6545 table_list->lock_type lock_type
6546 table_list->table table
6547 */
6548
6549 113303 TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
6550 uint lock_flags) {
6551 TABLE *table;
6552
1/2
✓ Branch 0 taken 113320 times.
✗ Branch 1 not taken.
113303 Open_table_context ot_ctx(thd, lock_flags);
6553 bool error;
6554
1/2
✓ Branch 0 taken 113316 times.
✗ Branch 1 not taken.
113320 DBUG_TRACE;
6555
6556 /* should not be used in a prelocked_mode context, see NOTE above */
6557
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 113316 times.
113316 assert(thd->locked_tables_mode < LTM_PRELOCKED);
6558
6559
2/2
✓ Branch 0 taken 74479 times.
✓ Branch 1 taken 38837 times.
113316 if (!(thd->state_flags & Open_tables_state::SYSTEM_TABLES))
6560
1/2
✓ Branch 0 taken 74481 times.
✗ Branch 1 not taken.
74479 THD_STAGE_INFO(thd, stage_opening_tables);
6561
6562 /* open_ltable can be used only for BASIC TABLEs */
6563 113318 table_list->required_type = dd::enum_table_type::BASE_TABLE;
6564
6565 /* This function can't properly handle requests for such metadata locks. */
6566
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 113320 times.
113318 assert(!table_list->mdl_request.is_ddl_or_lock_tables_lock_request());
6567
6568
5/8
✓ Branch 0 taken 113313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 113307 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 113313 times.
113326 while ((error = open_table(thd, table_list, &ot_ctx)) &&
6569 6 ot_ctx.can_recover_from_failed_open()) {
6570 /*
6571 Even though we have failed to open table we still need to
6572 call release_transactional_locks() to release metadata locks which
6573 might have been acquired successfully.
6574 */
6575 thd->mdl_context.rollback_to_savepoint(ot_ctx.start_of_statement_svp());
6576 table_list->mdl_request.ticket = nullptr;
6577 if (ot_ctx.recover_from_failed_open()) break;
6578 }
6579
6580
2/2
✓ Branch 0 taken 113304 times.
✓ Branch 1 taken 9 times.
113313 if (!error) {
6581 /*
6582 We can't have a view or some special "open_strategy" in this function
6583 so there should be a TABLE instance.
6584 */
6585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 113304 times.
113304 assert(table_list->table);
6586 113304 table = table_list->table;
6587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 113304 times.
113304 if (table->file->ht->db_type == DB_TYPE_MRG_MYISAM) {
6588 /* A MERGE table must not come here. */
6589 /* purecov: begin tested */
6590 my_error(ER_WRONG_OBJECT, MYF(0), table->s->db.str,
6591 table->s->table_name.str, "BASE TABLE");
6592 table = nullptr;
6593 goto end;
6594 /* purecov: end */
6595 }
6596
6597 113304 table_list->set_lock({lock_type, THR_DEFAULT});
6598
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 113298 times.
113298 if (thd->locked_tables_mode) {
6599 if (check_lock_and_start_stmt(thd, thd->lex, table_list)) table = nullptr;
6600 } else {
6601
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 113298 times.
113298 assert(thd->lock == nullptr); // You must lock everything at once
6602
1/2
✓ Branch 0 taken 113302 times.
✗ Branch 1 not taken.
113298 if ((table->reginfo.lock_type = lock_type) != TL_UNLOCK)
6603 113304 if (!(thd->lock =
6604
3/4
✓ Branch 0 taken 113304 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 113303 times.
113302 mysql_lock_tables(thd, &table_list->table, 1, lock_flags))) {
6605 1 table = nullptr;
6606 }
6607 }
6608 } else
6609 9 table = nullptr;
6610
6611 113309 end:
6612
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 113302 times.
113309 if (table == nullptr) {
6613
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
7 if (!thd->in_sub_stmt) trans_rollback_stmt(thd);
6614
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 close_thread_tables(thd);
6615 }
6616 113306 return table;
6617 113309 }
6618
6619 /**
6620 Open all tables in list, locks them and optionally process derived tables.
6621
6622 @param thd Thread context.
6623 @param tables List of tables for open and locking.
6624 @param flags Bitmap of options to be used to open and lock
6625 tables (see open_tables() and mysql_lock_tables()
6626 for details).
6627 @param prelocking_strategy Strategy which specifies how prelocking algorithm
6628 should work for this statement.
6629
6630 @note
6631 The thr_lock locks will automatically be freed by close_thread_tables().
6632
6633 @note
6634 open_and_lock_tables() is not intended for open-and-locking system tables
6635 in those cases when execution of statement has started already and other
6636 tables have been opened. Use open_trans_system_tables_for_read() instead.
6637
6638 @retval false OK.
6639 @retval true Error
6640 */
6641
6642 12212108 bool open_and_lock_tables(THD *thd, TABLE_LIST *tables, uint flags,
6643 Prelocking_strategy *prelocking_strategy) {
6644 uint counter;
6645
1/2
✓ Branch 0 taken 12212602 times.
✗ Branch 1 not taken.
12212108 MDL_savepoint mdl_savepoint = thd->mdl_context.mdl_savepoint();
6646
1/2
✓ Branch 0 taken 12212658 times.
✗ Branch 1 not taken.
12212602 DBUG_TRACE;
6647
6648 /*
6649 open_and_lock_tables() must not be used to open system tables. There must
6650 be no active attachable transaction when open_and_lock_tables() is called.
6651 Exception is made to the read-write attachables with explicitly specified
6652 in the assert table.
6653 Callers in the read-write case must make sure no side effect to
6654 the global transaction state is inflicted when the attachable one
6655 will commit.
6656 */
6657
4/10
✓ Branch 0 taken 12212665 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12212678 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12212351 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12212351 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
12212658 assert(!thd->is_attachable_ro_transaction_active() &&
6658 (!thd->is_attachable_rw_transaction_active() ||
6659 !strcmp(tables->table_name, "gtid_executed")));
6660
6661
3/4
✓ Branch 0 taken 12212635 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3075 times.
✓ Branch 3 taken 12209560 times.
12212375 if (open_tables(thd, &tables, &counter, flags, prelocking_strategy)) goto err;
6662
6663
2/6
✓ Branch 0 taken 12209470 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12209470 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
12209560 DBUG_EXECUTE_IF("sleep_open_and_lock_after_open", {
6664 const char *old_proc_info = thd->proc_info();
6665 thd->set_proc_info("DBUG sleep");
6666 my_sleep(6000000);
6667 thd->set_proc_info(old_proc_info);
6668 });
6669
6670
3/4
✓ Branch 0 taken 12209284 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 12209262 times.
12209470 if (lock_tables(thd, tables, counter, flags)) goto err;
6671
6672 12209262 return false;
6673 3097 err:
6674 // Rollback the statement execution done so far
6675
3/4
✓ Branch 0 taken 3079 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 3079 times.
✗ Branch 3 not taken.
3097 if (!thd->in_sub_stmt) trans_rollback_stmt(thd);
6676
1/2
✓ Branch 0 taken 3097 times.
✗ Branch 1 not taken.
3097 close_thread_tables(thd);
6677 /* Don't keep locks for a failed statement. */
6678
1/2
✓ Branch 0 taken 3097 times.
✗ Branch 1 not taken.
3097 thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
6679 3097 return true;
6680 12212359 }
6681
6682 /**
6683 Check if a secondary engine can be used to execute the current
6684 statement, and if so, replace the opened tables with their secondary
6685 counterparts.
6686
6687 @param thd thread handler
6688 @param flags bitmap of flags to pass to open_table
6689 @return true if an error is raised, false otherwise
6690 */
6691 26139768 static bool open_secondary_engine_tables(THD *thd, uint flags) {
6692 26139768 LEX *const lex = thd->lex;
6693 26139768 Sql_cmd *const sql_cmd = lex->m_sql_cmd;
6694
6695 // The previous execution context should have been destroyed.
6696
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26140149 times.
26139768 assert(lex->secondary_engine_execution_context() == nullptr);
6697
6698 // If use of secondary engines has been disabled for the statement,
6699 // there is nothing to do.
6700
6/6
✓ Branch 0 taken 24503761 times.
✓ Branch 1 taken 1636388 times.
✓ Branch 2 taken 219089 times.
✓ Branch 3 taken 24284446 times.
✓ Branch 4 taken 1855480 times.
✓ Branch 5 taken 24284443 times.
26140149 if (sql_cmd == nullptr || sql_cmd->secondary_storage_engine_disabled())
6701 1855480 return false;
6702
6703 // If the user has requested the use of a secondary storage engine
6704 // for this statement, skip past the initial optimization for the
6705 // primary storage engine and go straight to the secondary engine.
6706 24284443 if (thd->secondary_engine_optimization() ==
6707
4/4
✓ Branch 0 taken 20136542 times.
✓ Branch 1 taken 4148088 times.
✓ Branch 2 taken 86 times.
✓ Branch 3 taken 24284544 times.
44421172 Secondary_engine_optimization::PRIMARY_TENTATIVELY &&
6708
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 20136456 times.
20136542 thd->variables.use_secondary_engine == SECONDARY_ENGINE_FORCED) {
6709 86 thd->set_secondary_engine_optimization(
6710 Secondary_engine_optimization::SECONDARY);
6711
1/2
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
86 mysql_thread_set_secondary_engine(true);
6712
1/2
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
86 mysql_statement_set_secondary_engine(thd->m_statement_psi, true);
6713 }
6714
6715 // Only open secondary engine tables if use of a secondary engine
6716 // has been requested.
6717
2/2
✓ Branch 0 taken 24284396 times.
✓ Branch 1 taken 417 times.
24284630 if (thd->secondary_engine_optimization() !=
6718 Secondary_engine_optimization::SECONDARY)
6719 24284396 return false;
6720
6721 // If the statement cannot be executed in a secondary engine because
6722 // of a property of the statement, do not attempt to open the
6723 // secondary tables. Also disable use of secondary engines for
6724 // future executions of the statement, since these properties will
6725 // not change between executions.
6726 const LEX_CSTRING *secondary_engine =
6727
1/2
✓ Branch 0 taken 439 times.
✗ Branch 1 not taken.
420 sql_cmd->eligible_secondary_storage_engine();
6728 const plugin_ref secondary_engine_plugin =
6729 secondary_engine == nullptr
6730
2/2
✓ Branch 0 taken 404 times.
✓ Branch 1 taken 35 times.
439 ? nullptr
6731
1/2
✓ Branch 0 taken 404 times.
✗ Branch 1 not taken.
404 : ha_resolve_by_name(thd, secondary_engine, false);
6732
6733
4/4
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 400 times.
839 if ((secondary_engine_plugin == nullptr) ||
6734
2/4
✓ Branch 0 taken 400 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 400 times.
400 !plugin_is_ready(*secondary_engine, MYSQL_STORAGE_ENGINE_PLUGIN)) {
6735 // Didn't find a secondary storage engine to use for the query.
6736 39 sql_cmd->disable_secondary_storage_engine();
6737 39 return false;
6738 }
6739
6740 // If the statement cannot be executed in a secondary engine because
6741 // of a property of the environment, do not attempt to open the
6742 // secondary tables. However, do not disable use of secondary
6743 // storage engines for future executions of the statement, since the
6744 // environment may change before the next execution.
6745
3/4
✓ Branch 0 taken 400 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 399 times.
400 if (!thd->is_secondary_storage_engine_eligible()) return false;
6746
6747 399 auto hton = plugin_data<const handlerton *>(secondary_engine_plugin);
6748 399 sql_cmd->use_secondary_storage_engine(hton);
6749
6750 // Replace the TABLE objects in the TABLE_LIST with secondary tables.
6751
1/2
✓ Branch 0 taken 399 times.
✗ Branch 1 not taken.
399 Open_table_context ot_ctx(thd, flags | MYSQL_OPEN_SECONDARY_ENGINE);
6752 399 TABLE_LIST *tl = lex->query_tables;
6753 // For INSERT INTO SELECT and CTAS statements, the table to insert into does
6754 // not have to have a secondary engine. This table is always first in the list
6755
2/2
✓ Branch 0 taken 390 times.
✓ Branch 1 taken 9 times.
399 if ((lex->sql_command == SQLCOM_INSERT_SELECT ||
6756
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 386 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
399 lex->sql_command == SQLCOM_CREATE_TABLE) &&
6757 tl != nullptr)
6758 13 tl = tl->next_global;
6759
2/2
✓ Branch 0 taken 606 times.
✓ Branch 1 taken 303 times.
909 for (; tl != nullptr; tl = tl->next_global) {
6760
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 549 times.
606 if (tl->is_placeholder()) continue;
6761 549 TABLE *primary_table = tl->table;
6762 549 tl->table = nullptr;
6763
3/4
✓ Branch 0 taken 549 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 453 times.
549 if (open_table(thd, tl, &ot_ctx)) {
6764
2/4
✓ Branch 0 taken 96 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 96 times.
96 if (!thd->is_error()) {
6765 /*
6766 open_table() has not registered any error, implying that we can
6767 retry the failed open; but it is complicated to do so reliably, so we
6768 prefer to simply fail and re-prepare the statement in the primary
6769 engine, as an exceptional case. So we register an error.
6770 */
6771 my_error(ER_SECONDARY_ENGINE_PLUGIN, MYF(0),
6772 "Transient error when opening tables in RAPID");
6773 }
6774 96 return true;
6775 }
6776
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 453 times.
453 assert(tl->table->s->is_secondary_engine());
6777
1/2
✓ Branch 0 taken 453 times.
✗ Branch 1 not taken.
453 tl->table->file->ha_set_primary_handler(primary_table->file);
6778 }
6779
6780 // Prepare the secondary engine for executing the statement.
6781
1/2
✓ Branch 0 taken 303 times.
✗ Branch 1 not taken.
606 return hton->prepare_secondary_engine != nullptr &&
6782
3/4
✓ Branch 0 taken 303 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 302 times.
606 hton->prepare_secondary_engine(thd, lex);
6783 }
6784
6785 /**
6786 Open all tables for a query or statement, in list started by "tables"
6787
6788 @param thd thread handler
6789 @param tables list of tables for open
6790 @param flags bitmap of flags to modify how the tables will be open:
6791 MYSQL_LOCK_IGNORE_FLUSH - open table even if someone has
6792 done a flush on it.
6793
6794 @retval false - ok
6795 @retval true - error
6796
6797 @note
6798 This is to be used on prepare stage when you don't read any
6799 data from the tables.
6800
6801 @note
6802 Updates Query_tables_list::table_count as side-effect.
6803 */
6804
6805 26160297 bool open_tables_for_query(THD *thd, TABLE_LIST *tables, uint flags) {
6806 26160297 DML_prelocking_strategy prelocking_strategy;
6807
1/2
✓ Branch 0 taken 26161039 times.
✗ Branch 1 not taken.
26160297 MDL_savepoint mdl_savepoint = thd->mdl_context.mdl_savepoint();
6808
1/2
✓ Branch 0 taken 26161054 times.
✗ Branch 1 not taken.
26161039 DBUG_TRACE;
6809
6810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26161054 times.
26161054 assert(tables == thd->lex->query_tables);
6811
6812
3/4
✓ Branch 0 taken 26160908 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20379 times.
✓ Branch 3 taken 26140529 times.
26161054 if (open_tables(thd, &tables, &thd->lex->table_count, flags,
6813 &prelocking_strategy))
6814 20379 goto end;
6815
6816
3/4
✓ Branch 0 taken 26139998 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 97 times.
✓ Branch 3 taken 26139901 times.
26140529 if (open_secondary_engine_tables(thd, flags)) goto end;
6817
6818 26139901 return false;
6819 20476 end:
6820 /*
6821 No need to commit/rollback the statement transaction: it's
6822 either not started or we're filling in an INFORMATION_SCHEMA
6823 table on the fly, and thus mustn't manipulate with the
6824 transaction of the enclosing statement.
6825 */
6826
5/6
✓ Branch 0 taken 1021 times.
✓ Branch 1 taken 19456 times.
✓ Branch 2 taken 1014 times.
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1014 times.
20476 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT) ||
6827 (thd->state_flags & Open_tables_state::BACKUPS_AVAIL) ||
6828 thd->in_sub_stmt);
6829
1/2
✓ Branch 0 taken 20477 times.
✗ Branch 1 not taken.
20477 close_thread_tables(thd);
6830 /* Don't keep locks for a failed statement. */
6831
1/2
✓ Branch 0 taken 20477 times.
✗ Branch 1 not taken.
20477 thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
6832
6833 20477 return true; /* purecov: inspected */
6834 26160378 }
6835
6836 /*
6837 Mark all real tables in the list as free for reuse.
6838
6839 SYNOPSIS
6840 mark_real_tables_as_free_for_reuse()
6841 thd - thread context
6842 table - head of the list of tables
6843
6844 DESCRIPTION
6845 Marks all real tables in the list (i.e. not views, derived
6846 or schema tables) as free for reuse.
6847 */
6848
6849 2333685 static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table_list) {
6850 TABLE_LIST *table;
6851
2/2
✓ Branch 0 taken 21308 times.
✓ Branch 1 taken 2333685 times.
2354993 for (table = table_list; table; table = table->next_global)
6852
2/2
✓ Branch 0 taken 21123 times.
✓ Branch 1 taken 185 times.
21308 if (!table->is_placeholder()) {
6853 21123 table->table->query_id = 0;
6854 }
6855
2/2
✓ Branch 0 taken 21308 times.
✓ Branch 1 taken 2333685 times.
2354993 for (table = table_list; table; table = table->next_global)
6856
5/6
✓ Branch 0 taken 21123 times.
✓ Branch 1 taken 185 times.
✓ Branch 2 taken 21123 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 21123 times.
✓ Branch 5 taken 185 times.
21308 if (!table->is_placeholder() && table->table->db_stat) {
6857 /*
6858 Detach children of MyISAMMRG tables used in
6859 sub-statements, they will be reattached at open.
6860 This has to be done in a separate loop to make sure
6861 that children have had their query_id cleared.
6862 */
6863 21123 table->table->file->ha_extra(HA_EXTRA_DETACH_CHILDREN);
6864 }
6865 2333685 }
6866
6867 /**
6868 Lock all tables in a list.
6869
6870 @param thd Thread handler
6871 @param tables Tables to lock
6872 @param count Number of opened tables
6873 @param flags Options (see mysql_lock_tables() for details)
6874
6875 You can't call lock_tables() while holding thr_lock locks, as
6876 this would break the dead-lock-free handling thr_lock gives us.
6877 You must always get all needed locks at once.
6878
6879 If the query for which we are calling this function is marked as
6880 requiring prelocking, this function will change
6881 locked_tables_mode to LTM_PRELOCKED.
6882
6883 @retval false Success.
6884 @retval true A lock wait timeout, deadlock or out of memory.
6885 */
6886
6887 38319992 bool lock_tables(THD *thd, TABLE_LIST *tables, uint count, uint flags) {
6888 TABLE_LIST *table;
6889
6890
1/2
✓ Branch 0 taken 38321325 times.
✗ Branch 1 not taken.
38319992 DBUG_TRACE;
6891 /*
6892 We can't meet statement requiring prelocking if we already
6893 in prelocked mode.
6894 */
6895
3/4
✓ Branch 0 taken 664877 times.
✓ Branch 1 taken 37656448 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 664906 times.
38321325 assert(thd->locked_tables_mode <= LTM_LOCK_TABLES ||
6896 !thd->lex->requires_prelocking());
6897
6898 /*
6899 lock_tables() should not be called if this statement has
6900 already locked its tables.
6901 */
6902
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38321354 times.
38321354 assert(thd->lex->lock_tables_state == Query_tables_list::LTS_NOT_LOCKED);
6903
6904
6/6
✓ Branch 0 taken 19207921 times.
✓ Branch 1 taken 19113433 times.
✓ Branch 2 taken 19201267 times.
✓ Branch 3 taken 6409 times.
✓ Branch 4 taken 19201307 times.
✓ Branch 5 taken 19119802 times.
38321354 if (!tables && !thd->lex->requires_prelocking()) {
6905 /*
6906 Even though we are not really locking any tables mark this
6907 statement as one that has locked its tables, so we won't
6908 call this function second time for the same execution of
6909 the same statement.
6910 */
6911 19201307 thd->lex->lock_tables_state = Query_tables_list::LTS_LOCKED;
6912
1/2
✓ Branch 0 taken 19201599 times.
✗ Branch 1 not taken.
19201307 int ret = thd->decide_logging_format(tables);
6913 19201599 return ret;
6914 }
6915
6916 /*
6917 Check for thd->locked_tables_mode to avoid a redundant
6918 and harmful attempt to lock the already locked tables again.
6919 Checking for thd->lock is not enough in some situations. For example,
6920 if a stored function contains
6921 "drop table t3; create temporary t3 ..; insert into t3 ...;"
6922 thd->lock may be 0 after drop tables, whereas locked_tables_mode
6923 is still on. In this situation an attempt to lock temporary
6924 table t3 will lead to a memory leak.
6925 */
6926
2/2
✓ Branch 0 taken 19068898 times.
✓ Branch 1 taken 50904 times.
19119802 if (!thd->locked_tables_mode) {
6927
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19068898 times.
19068898 assert(thd->lock == nullptr); // You must lock everything at once
6928 TABLE **start, **ptr;
6929
6930
2/4
✓ Branch 0 taken 19069044 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19069044 times.
19068898 if (!(ptr = start = (TABLE **)thd->alloc(sizeof(TABLE *) * count)))
6931 return true;
6932
2/2
✓ Branch 0 taken 22801131 times.
✓ Branch 1 taken 19069388 times.
41870519 for (table = tables; table; table = table->next_global) {
6933
4/4
✓ Branch 0 taken 21824621 times.
✓ Branch 1 taken 976854 times.
✓ Branch 2 taken 21824164 times.
✓ Branch 3 taken 977311 times.
44625752 if (!table->is_placeholder() &&
6934 /*
6935 Do not call handler::store_lock()/external_lock() for temporary
6936 tables from prelocking list.
6937
6938 Prelocking algorithm does not add element for a table to the
6939 prelocking list if it finds that the routine that uses the table can
6940 create it as a temporary during its execution. Note that such
6941 routine actually can use existing temporary table if its CREATE
6942 TEMPORARY TABLE has IF NOT EXISTS clause. For such tables we rely on
6943 calls to handler::start_stmt() done by routine's substatement when
6944 it accesses the table to inform storage engine about table
6945 participation in transaction and type of operation carried out,
6946 instead of calls to handler::store_lock()/external_lock() done at
6947 prelocking stage.
6948
6949 In cases when statement uses two routines one of which can create
6950 temporary table and modifies it, while another only reads from this
6951 table, storage engine might be confused about real operation type
6952 performed by the whole statement. Calls to
6953 handler::store_lock()/external_lock() done at prelocking stage will
6954 inform SE only about read part, while information about modification
6955 will be delayed until handler::start_stmt() call during execution of
6956 the routine doing modification. InnoDB considers this breaking of
6957 promise about operation type and fails on assertion.
6958
6959 To avoid this problem we try to handle both the cases when temporary
6960 table can be created by routine and the case when it is created
6961 outside of routine and only accessed by it, uniformly. We don't call
6962 handler::store_lock()/external_lock() for temporary tables used by
6963 routines at prelocking stage and rely on calls to
6964 handler::start_stmt(), which happen during substatement execution,
6965 to pass correct information about operation type instead.
6966 */
6967
2/2
✓ Branch 0 taken 21183 times.
✓ Branch 1 taken 21803438 times.
21824621 !(table->prelocking_placeholder &&
6968
2/2
✓ Branch 0 taken 20727 times.
✓ Branch 1 taken 456 times.
21183 table->table->s->tmp_table != NO_TMP_TABLE)) {
6969 21824164 *(ptr++) = table->table;
6970 }
6971 }
6972
6973
3/4
✓ Branch 0 taken 16421684 times.
✓ Branch 1 taken 2647240 times.
✓ Branch 2 taken 16422259 times.
✗ Branch 3 not taken.
19069388 DEBUG_SYNC(thd, "before_lock_tables_takes_lock");
6974
6975 19069326 if (!(thd->lock =
6976
3/4
✓ Branch 0 taken 19069326 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1127 times.
✓ Branch 3 taken 19068199 times.
19069499 mysql_lock_tables(thd, start, (uint)(ptr - start), flags)))
6977 1127 return true;
6978
6979
3/4
✓ Branch 0 taken 16420752 times.
✓ Branch 1 taken 2647336 times.
✓ Branch 2 taken 16421202 times.
✗ Branch 3 not taken.
19068199 DEBUG_SYNC(thd, "after_lock_tables_takes_lock");
6980
6981
4/4
✓ Branch 0 taken 2333704 times.
✓ Branch 1 taken 16734576 times.
✓ Branch 2 taken 2333621 times.
✓ Branch 3 taken 16734659 times.
21402242 if (thd->lex->requires_prelocking() &&
6982
2/2
✓ Branch 0 taken 2333621 times.
✓ Branch 1 taken 83 times.
2333704 thd->lex->sql_command != SQLCOM_LOCK_TABLES) {
6983 2333621 TABLE_LIST *first_not_own = thd->lex->first_not_own_table();
6984 /*
6985 We just have done implicit LOCK TABLES, and now we have
6986 to emulate first open_and_lock_tables() after it.
6987
6988 When open_and_lock_tables() is called for a single table out of
6989 a table list, the 'next_global' chain is temporarily broken. We
6990 may not find 'first_not_own' before the end of the "list".
6991 Look for example at those places where open_n_lock_single_table()
6992 is called. That function implements the temporary breaking of
6993 a table list for opening a single table.
6994 */
6995
4/4
✓ Branch 0 taken 2364148 times.
✓ Branch 1 taken 2321320 times.
✓ Branch 2 taken 2351847 times.
✓ Branch 3 taken 12301 times.
4685468 for (table = tables; table && table != first_not_own;
6996 2351847 table = table->next_global) {
6997
2/2
✓ Branch 0 taken 2351384 times.
✓ Branch 1 taken 463 times.
2351847 if (!table->is_placeholder()) {
6998 2351384 table->table->query_id = thd->query_id;
6999
3/6
✓ Branch 0 taken 2351384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2351384 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2351384 times.
2351384 if (check_lock_and_start_stmt(thd, thd->lex, table)) {
7000 mysql_unlock_tables(thd, thd->lock);
7001 thd->lock = nullptr;
7002 return true;
7003 }
7004 }
7005 }
7006 /*
7007 Let us mark all tables which don't belong to the statement itself,
7008 and was marked as occupied during open_tables() as free for reuse.
7009 */
7010
1/2
✓ Branch 0 taken 2333621 times.
✗ Branch 1 not taken.
2333621 mark_real_tables_as_free_for_reuse(first_not_own);
7011
5/8
✓ Branch 0 taken 2333621 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2333621 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2333620 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2333621 DBUG_PRINT("info", ("locked_tables_mode= LTM_PRELOCKED"));
7012
1/2
✓ Branch 0 taken 2333621 times.
✗ Branch 1 not taken.
2333621 thd->enter_locked_tables_mode(LTM_PRELOCKED);
7013 }
7014 } else {
7015 /*
7016 When we implicitly open DD tables used by a IS query in LOCK TABLE mode,
7017 we do not go through mysql_lock_tables(), which sets lock type to use
7018 by SE. Here, we request SE to use read lock for these implicitly opened
7019 DD tables using ha_external_lock().
7020
7021 TODO: In PRELOCKED under LOCKED TABLE mode, if sub-statement is a IS
7022 query then for DD table ha_external_lock is called more than once.
7023 This works for now as in this mode each sub-statement gets its own
7024 brand new TABLE instances for each table.
7025 Allocating a brand new TABLE instances for each sub-statement is
7026 a resources wastage. Once this issue is fixed, following code
7027 should be adjusted to not to call ha_external_lock in sub-statement
7028 mode (similar to how code in close_thread_table() behaves).
7029 */
7030
2/2
✓ Branch 0 taken 11465 times.
✓ Branch 1 taken 39068 times.
50904 if (in_LTM(thd)) {
7031
2/2
✓ Branch 0 taken 58669 times.
✓ Branch 1 taken 11465 times.
70134 for (table = tables; table; table = table->next_global) {
7032 58669 TABLE *tbl = table->table;
7033
6/6
✓ Branch 0 taken 45536 times.
✓ Branch 1 taken 13133 times.
✓ Branch 2 taken 41287 times.
✓ Branch 3 taken 4249 times.
✓ Branch 4 taken 41287 times.
✓ Branch 5 taken 17382 times.
58669 if (tbl && belongs_to_dd_table(table)) {
7034
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41287 times.
41287 assert(tbl->file->get_lock_type() == F_UNLCK);
7035
1/2
✓ Branch 0 taken 41287 times.
✗ Branch 1 not taken.
41287 tbl->file->init_table_handle_for_HANDLER();
7036
1/2
✓ Branch 0 taken 41287 times.
✗ Branch 1 not taken.
41287 tbl->file->ha_external_lock(thd, F_RDLCK);
7037 }
7038 }
7039 }
7040
7041 50533 TABLE_LIST *first_not_own = thd->lex->first_not_own_table();
7042 /*
7043 When open_and_lock_tables() is called for a single table out of
7044 a table list, the 'next_global' chain is temporarily broken. We
7045 may not find 'first_not_own' before the end of the "list".
7046 Look for example at those places where open_n_lock_single_table()
7047 is called. That function implements the temporary breaking of
7048 a table list for opening a single table.
7049 */
7050
4/4
✓ Branch 0 taken 98553 times.
✓ Branch 1 taken 50454 times.
✓ Branch 2 taken 98511 times.
✓ Branch 3 taken 42 times.
149007 for (table = tables; table && table != first_not_own;
7051 98474 table = table->next_global) {
7052
2/2
✓ Branch 0 taken 13657 times.
✓ Branch 1 taken 84854 times.
98511 if (table->is_placeholder()) continue;
7053
7054 /*
7055 In a stored function or trigger we should ensure that we won't change
7056 a table that is already used by the calling statement.
7057 */
7058
4/4
✓ Branch 0 taken 39739 times.
✓ Branch 1 taken 45115 times.
✓ Branch 2 taken 28002 times.
✓ Branch 3 taken 56852 times.
124593 if (thd->locked_tables_mode >= LTM_PRELOCKED &&
7059
2/2
✓ Branch 0 taken 28002 times.
✓ Branch 1 taken 11737 times.
39739 table->lock_descriptor().type >= TL_WRITE_ALLOW_WRITE) {
7060
2/2
✓ Branch 0 taken 89380 times.
✓ Branch 1 taken 27983 times.
117363 for (TABLE *opentab = thd->open_tables; opentab;
7061 89361 opentab = opentab->next) {
7062
4/4
✓ Branch 0 taken 29676 times.
✓ Branch 1 taken 59704 times.
✓ Branch 2 taken 27612 times.
✓ Branch 3 taken 2064 times.
89380 if (table->table->s == opentab->s && opentab->query_id &&
7063
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 27593 times.
27612 table->table->query_id != opentab->query_id) {
7064 19 my_error(ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG, MYF(0),
7065
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 table->table->s->table_name.str);
7066 19 return true;
7067 }
7068 }
7069 }
7070
7071
4/6
✓ Branch 0 taken 84835 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 84835 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 18 times.
✓ Branch 5 taken 84817 times.
84835 if (check_lock_and_start_stmt(thd, thd->lex, table)) {
7072 18 return true;
7073 }
7074 }
7075 /*
7076 If we are under explicit LOCK TABLES and our statement requires
7077 prelocking, we should mark all "additional" tables as free for use
7078 and enter prelocked mode.
7079 */
7080
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 50432 times.
50496 if (thd->lex->requires_prelocking()) {
7081
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
64 mark_real_tables_as_free_for_reuse(first_not_own);
7082
3/8
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 64 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
64 DBUG_PRINT("info",
7083 ("thd->locked_tables_mode= LTM_PRELOCKED_UNDER_LOCK_TABLES"));
7084 64 thd->locked_tables_mode = LTM_PRELOCKED_UNDER_LOCK_TABLES;
7085 }
7086 }
7087
7088 /*
7089 Mark the statement as having tables locked. For purposes
7090 of Query_tables_list::lock_tables_state we treat any
7091 statement which passes through lock_tables() as such.
7092 */
7093 19118776 thd->lex->lock_tables_state = Query_tables_list::LTS_LOCKED;
7094
7095
1/2
✓ Branch 0 taken 19118352 times.
✗ Branch 1 not taken.
19118776 int ret = thd->decide_logging_format(tables);
7096 19118352 return ret;
7097 38321115 }
7098
7099 /**
7100 Simplified version of lock_tables() call to be used for locking
7101 data-dictionary tables when reading or storing data-dictionary
7102 objects.
7103
7104 @note The main reason why this function exists is that it avoids
7105 allocating temporary buffer on memory root of statement.
7106 As result it can be called many times (e.g. thousands)
7107 during DDL statement execution without hogging memory.
7108 */
7109
7110 21759229 bool lock_dictionary_tables(THD *thd, TABLE_LIST *tables, uint count,
7111 uint flags) {
7112
1/2
✓ Branch 0 taken 21759255 times.
✗ Branch 1 not taken.
21759229 DBUG_TRACE;
7113
7114 // We always open at least one DD table.
7115
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21759255 times.
21759255 assert(tables);
7116 /*
7117 This function is supposed to be called after backing up and resetting
7118 to clean state Open_tables_state and Query_table_lists contexts.
7119 */
7120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21759255 times.
21759255 assert(thd->locked_tables_mode == LTM_NONE);
7121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21759251 times.
21759255 assert(!thd->lex->requires_prelocking());
7122
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21759251 times.
21759251 assert(thd->lex->lock_tables_state == Query_tables_list::LTS_NOT_LOCKED);
7123
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21759251 times.
21759251 assert(thd->lock == nullptr);
7124
7125 TABLE **start, **ptr;
7126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21759251 times.
21759251 if (!(ptr = start = (TABLE **)my_alloca(sizeof(TABLE *) * count)))
7127 return true;
7128
7129
2/2
✓ Branch 0 taken 95103887 times.
✓ Branch 1 taken 21759278 times.
116863165 for (TABLE_LIST *table = tables; table; table = table->next_global) {
7130 // Data-dictionary tables must be base tables.
7131
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 95103914 times.
95103887 assert(!table->is_placeholder());
7132
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95103914 times.
95103914 assert(table->table->s->tmp_table == NO_TMP_TABLE);
7133 // There should be no prelocking when DD code uses this call.
7134
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95103914 times.
95103914 assert(!table->prelocking_placeholder);
7135 95103914 *(ptr++) = table->table;
7136 }
7137
7138
3/4
✓ Branch 0 taken 20623825 times.
✓ Branch 1 taken 1135417 times.
✓ Branch 2 taken 20623840 times.
✗ Branch 3 not taken.
21759278 DEBUG_SYNC(thd, "before_lock_dictionary_tables_takes_lock");
7139
7140
2/4
✓ Branch 0 taken 21759254 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 21759254 times.
21759257 if (!(thd->lock = mysql_lock_tables(thd, start, (uint)(ptr - start), flags)))
7141 return true;
7142
7143 21759254 thd->lex->lock_tables_state = Query_tables_list::LTS_LOCKED;
7144
7145 21759254 return false;
7146 21759254 }
7147
7148 /**
7149 Prepare statement for reopening of tables and recalculation of set of
7150 prelocked tables.
7151
7152 @param[in] thd Thread context.
7153 @param[in,out] tables List of tables which we were trying to open
7154 and lock.
7155 @param[in] start_of_statement_svp MDL savepoint which represents the set
7156 of metadata locks which the current transaction
7157 managed to acquire before execution of the current
7158 statement and to which we should revert before
7159 trying to reopen tables. NULL if no metadata locks
7160 were held and thus all metadata locks should be
7161 released.
7162 */
7163
7164 37 void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
7165 const MDL_savepoint &start_of_statement_svp) {
7166 37 TABLE_LIST *first_not_own_table = thd->lex->first_not_own_table();
7167 TABLE_LIST *tmp;
7168
7169 /*
7170 If table list consists only from tables from prelocking set, table list
7171 for new attempt should be empty, so we have to update list's root pointer.
7172 */
7173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 if (first_not_own_table == *tables) *tables = nullptr;
7174 37 thd->lex->chop_off_not_own_tables();
7175
1/2
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
37 sp_remove_not_own_routines(thd->lex);
7176
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 37 times.
81 for (tmp = *tables; tmp; tmp = tmp->next_global) {
7177 44 tmp->table = nullptr;
7178 44 tmp->mdl_request.ticket = nullptr;
7179 /* We have to cleanup translation tables of views. */
7180 44 tmp->cleanup_items();
7181 }
7182 /*
7183 No need to commit/rollback the statement transaction: it's
7184 either not started or we're filling in an INFORMATION_SCHEMA
7185 table on the fly, and thus mustn't manipulate with the
7186 transaction of the enclosing statement.
7187 */
7188
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 36 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
37 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT) ||
7189 (thd->state_flags & Open_tables_state::BACKUPS_AVAIL));
7190 37 close_thread_tables(thd);
7191 37 thd->mdl_context.rollback_to_savepoint(start_of_statement_svp);
7192 37 }
7193
7194 /**
7195 Open a single table without table caching and don't add it to
7196 THD::open_tables. Depending on the 'add_to_temporary_tables_list' value,
7197 the opened TABLE instance will be added to THD::temporary_tables list.
7198
7199 @param thd Thread context.
7200 @param path Path (without .frm)
7201 @param db Database name.
7202 @param table_name Table name.
7203 @param add_to_temporary_tables_list Specifies if the opened TABLE
7204 instance should be linked into
7205 THD::temporary_tables list.
7206 @param open_in_engine Indicates that we need to open table
7207 in storage engine in addition to
7208 constructing TABLE object for it.
7209 @param table_def A data-dictionary Table-object describing
7210 table to be used for opening.
7211
7212 @note This function is used:
7213 - by alter_table() to open a temporary table;
7214 - when creating a temporary table with CREATE TEMPORARY TABLE.
7215
7216 @return TABLE instance for opened table.
7217 @retval NULL on error.
7218 */
7219
7220 146734 TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
7221 const char *table_name,
7222 bool add_to_temporary_tables_list,
7223 bool open_in_engine, const dd::Table &table_def) {
7224 TABLE *tmp_table;
7225 TABLE_SHARE *share;
7226 char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path;
7227 size_t key_length;
7228
1/2
✓ Branch 0 taken 146734 times.
✗ Branch 1 not taken.
146734 DBUG_TRACE;
7229
5/8
✓ Branch 0 taken 146734 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 146734 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 146733 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
146734 DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s' server_id: %u "
7230 "pseudo_thread_id: %lu",
7231 db, table_name, path, (uint)thd->server_id,
7232 (ulong)thd->variables.pseudo_thread_id));
7233
7234 /* Create the cache_key for temporary tables */
7235
1/2
✓ Branch 0 taken 146734 times.
✗ Branch 1 not taken.
146734 key_length = create_table_def_key_tmp(thd, db, table_name, cache_key);
7236
7237
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 146734 times.
146734 if (!(tmp_table = (TABLE *)my_malloc(
7238 key_memory_TABLE,
7239
1/2
✓ Branch 0 taken 146734 times.
✗ Branch 1 not taken.
146734 sizeof(*tmp_table) + sizeof(*share) + strlen(path) + 1 + key_length,
7240 MYF(MY_WME))))
7241 return nullptr; /* purecov: inspected */
7242
7243 #ifndef NDEBUG
7244 // In order to let purge thread callback call open_table_uncached()
7245 // we cannot grab LOCK_open here, as that will cause a deadlock.
7246
7247 // The assert below safeguards against opening a table which is
7248 // already found in the table definition cache. Iff the table will
7249 // be opened in the SE below, we may get two conflicting copies of
7250 // SE private data in the two table_shares.
7251
7252 // By only grabbing LOCK_open and check the assert only when
7253 // open_in_engine is true, we safeguard the engine private data while
7254 // also allowing the purge threads callbacks since they always call
7255 // with open_in_engine=false.
7256
2/2
✓ Branch 0 taken 71743 times.
✓ Branch 1 taken 74991 times.
146734 if (open_in_engine) {
7257
1/2
✓ Branch 0 taken 71743 times.
✗ Branch 1 not taken.
71743 mysql_mutex_lock(&LOCK_open);
7258
3/6
✓ Branch 0 taken 71743 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 71743 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 71743 times.
71743 assert(table_def_cache->count(string(cache_key, key_length)) == 0);
7259
1/2
✓ Branch 0 taken 71743 times.
✗ Branch 1 not taken.
71743 mysql_mutex_unlock(&LOCK_open);
7260 }
7261 #endif
7262
7263 146734 share = (TABLE_SHARE *)(tmp_table + 1);
7264 146734 tmp_path = (char *)(share + 1);
7265 146734 saved_cache_key = my_stpcpy(tmp_path, path) + 1;
7266 146734 memcpy(saved_cache_key, cache_key, key_length);
7267
7268 146734 init_tmp_table_share(thd, share, saved_cache_key, key_length,
7269
1/2
✓ Branch 0 taken 146734 times.
✗ Branch 1 not taken.
146734 strend(saved_cache_key) + 1, tmp_path, nullptr);
7270
7271
2/4
✓ Branch 0 taken 146734 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 146734 times.
146734 if (open_table_def(thd, share, table_def)) {
7272 /* No need to lock share->mutex as this is not needed for tmp tables */
7273 free_table_share(share);
7274 destroy(tmp_table);
7275 my_free(tmp_table);
7276 return nullptr;
7277 }
7278
7279 #ifdef HAVE_PSI_TABLE_INTERFACE
7280
1/2
✓ Branch 0 taken 146734 times.
✗ Branch 1 not taken.
146734 share->m_psi = PSI_TABLE_CALL(get_table_share)(true, share);
7281 #else
7282 share->m_psi = NULL;
7283 #endif
7284
7285
7/8
✓ Branch 0 taken 71743 times.
✓ Branch 1 taken 74991 times.
✓ Branch 2 taken 71743 times.
✓ Branch 3 taken 74991 times.
✓ Branch 4 taken 146734 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20 times.
✓ Branch 7 taken 146714 times.
146734 if (open_table_from_share(
7286 thd, share, table_name,
7287 open_in_engine
7288 ? (uint)(HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX)
7289 : 0,
7290 EXTRA_RECORD, ha_open_options, tmp_table,
7291 /*
7292 Set "is_create_table" if the table does not
7293 exist in SE
7294 */
7295 (open_in_engine ? false : true), &table_def)) {
7296 /* No need to lock share->mutex as this is not needed for tmp tables */
7297
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 free_table_share(share);
7298 20 destroy(tmp_table);
7299
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 my_free(tmp_table);
7300 20 return nullptr;
7301 }
7302
7303 146714 tmp_table->reginfo.lock_type = TL_WRITE; // Simulate locked
7304 146714 share->tmp_table =
7305
2/2
✓ Branch 0 taken 114896 times.
✓ Branch 1 taken 31818 times.
146714 (tmp_table->file->has_transactions() ? TRANSACTIONAL_TMP_TABLE
7306 : NON_TRANSACTIONAL_TMP_TABLE);
7307
7308
2/2
✓ Branch 0 taken 146637 times.
✓ Branch 1 taken 77 times.
146714 if (add_to_temporary_tables_list) {
7309 146637 tmp_table->set_tmp_dd_table_ptr(&table_def);
7310
1/2
✓ Branch 0 taken 146637 times.
✗ Branch 1 not taken.
146637 tmp_table->set_binlog_drop_if_temp(
7311
5/6
✓ Branch 0 taken 146637 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 65050 times.
✓ Branch 3 taken 81587 times.
✓ Branch 4 taken 3434 times.
✓ Branch 5 taken 61616 times.
211687 !thd->is_current_stmt_binlog_disabled() &&
7312 65050 !thd->is_current_stmt_binlog_format_row());
7313 /* growing temp list at the head */
7314
1/2
✓ Branch 0 taken 146637 times.
✗ Branch 1 not taken.
146637 mysql_mutex_lock(&thd->LOCK_temporary_tables);
7315 146637 tmp_table->next = thd->temporary_tables;
7316
2/2
✓ Branch 0 taken 6014 times.
✓ Branch 1 taken 140623 times.
146637 if (tmp_table->next) tmp_table->next->prev = tmp_table;
7317 146637 thd->temporary_tables = tmp_table;
7318 146637 thd->temporary_tables->prev = nullptr;
7319
2/2
✓ Branch 0 taken 2755 times.
✓ Branch 1 taken 143882 times.
146637 if (thd->slave_thread) {
7320 2755 ++atomic_replica_open_temp_tables;
7321
1/2
✓ Branch 0 taken 2755 times.
✗ Branch 1 not taken.
2755 ++thd->rli_slave->get_c_rli()->atomic_channel_open_temp_tables;
7322 }
7323
1/2
✓ Branch 0 taken 146637 times.
✗ Branch 1 not taken.
146637 mysql_mutex_unlock(&thd->LOCK_temporary_tables);
7324 }
7325 146714 tmp_table->pos_in_table_list = nullptr;
7326
7327
1/2
✓ Branch 0 taken 146714 times.
✗ Branch 1 not taken.
146714 tmp_table->set_created();
7328
7329
5/8
✓ Branch 0 taken 146714 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 146714 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 146713 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
146714 DBUG_PRINT("tmptable", ("opened table: '%s'.'%s' %p", tmp_table->s->db.str,
7330 tmp_table->s->table_name.str, tmp_table));
7331 146714 return tmp_table;
7332 146734 }
7333
7334 /**
7335 Delete a temporary table.
7336
7337 @param thd Thread handle
7338 @param base Handlerton for table to be deleted.
7339 @param path Path to the table to be deleted (without
7340 an extension).
7341 @param table_def dd::Table object describing temporary table
7342 to be deleted.
7343
7344 @retval false - success.
7345 @retval true - failure.
7346 */
7347
7348 52319 bool rm_temporary_table(THD *thd, handlerton *base, const char *path,
7349 const dd::Table *table_def) {
7350 52319 bool error = false;
7351 handler *file;
7352
1/2
✓ Branch 0 taken 52319 times.
✗ Branch 1 not taken.
52319 DBUG_TRACE;
7353
7354 156957 file = get_new_handler((TABLE_SHARE *)nullptr,
7355
2/4
✓ Branch 0 taken 52319 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52319 times.
✗ Branch 3 not taken.
52319 table_def->partition_type() != dd::Table::PT_NONE,
7356 thd->mem_root, base);
7357
4/8
✓ Branch 0 taken 52319 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52319 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 52319 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 52319 times.
52319 if (file && file->ha_delete_table(path, table_def)) {
7358 error = true;
7359 LogErr(WARNING_LEVEL, ER_FAILED_TO_REMOVE_TEMP_TABLE, path, my_errno());
7360 }
7361 52319 destroy(file);
7362 52319 return error;
7363 52319 }
7364
7365 /*****************************************************************************
7366 * The following find_field_in_XXX procedures implement the core of the
7367 * name resolution functionality. The entry point to resolve a column name in a
7368 * list of tables is 'find_field_in_tables'. It calls 'find_field_in_table_ref'
7369 * for each table reference. In turn, depending on the type of table reference,
7370 * 'find_field_in_table_ref' calls one of the 'find_field_in_XXX' procedures
7371 * below specific for the type of table reference.
7372 *
7373 * @todo: Refactor the error handling system used by these functions, so that
7374 * it is clear when an error is reported and when an empty reference
7375 * is returned.
7376 *
7377 ******************************************************************************/
7378
7379 /* Special Field pointers as return values of find_field_in_XXX functions. */
7380 Field *not_found_field = (Field *)0x1;
7381 Field *view_ref_found = (Field *)0x2;
7382
7383 #define WRONG_GRANT (Field *)-1
7384
7385 /**
7386 Find a temporary table specified by TABLE_LIST instance in the cache and
7387 prepare its TABLE instance for use.
7388
7389 This function tries to resolve this table in the list of temporary tables
7390 of this thread. Temporary tables are thread-local and "shadow" base
7391 tables with the same name.
7392
7393 @note In most cases one should use open_temporary_tables() instead
7394 of this call.
7395
7396 @note One should finalize process of opening temporary table for table
7397 list element by calling open_and_process_table(). This function
7398 is responsible for table version checking and handling of merge
7399 tables.
7400
7401 @note We used to check global_read_lock before opening temporary tables.
7402 However, that limitation was artificial and is removed now.
7403
7404 @return Error status.
7405 @retval false On success. If a temporary table exists for the given
7406 key, tl->table is set.
7407 @retval true On error. my_error() has been called.
7408 */
7409
7410 19158897 bool open_temporary_table(THD *thd, TABLE_LIST *tl) {
7411
1/2
✓ Branch 0 taken 19159336 times.
✗ Branch 1 not taken.
19158897 DBUG_TRACE;
7412
5/8
✓ Branch 0 taken 19159261 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19159340 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 73 times.
✓ Branch 5 taken 19159267 times.
✓ Branch 6 taken 85 times.
✗ Branch 7 not taken.
19159336 DBUG_PRINT("enter", ("table: '%s'.'%s'", tl->db, tl->table_name));
7413
7414 /*
7415 Code in open_table() assumes that TABLE_LIST::table can
7416 be non-zero only for pre-opened temporary tables.
7417 */
7418
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 19159351 times.
19159351 assert(tl->table == nullptr);
7419
7420 /*
7421 This function should not be called for cases when derived or I_S
7422 tables can be met since table list elements for such tables can
7423 have invalid db or table name.
7424 Instead open_temporary_tables() should be used.
7425 */
7426
3/4
✓ Branch 0 taken 19159060 times.
✓ Branch 1 taken 300 times.
✓ Branch 2 taken 19159071 times.
✗ Branch 3 not taken.
19159351 assert(!tl->is_view_or_derived() && !tl->schema_table);
7427
7428
2/2
✓ Branch 0 taken 839597 times.
✓ Branch 1 taken 18319474 times.
19159071 if (tl->open_type == OT_BASE_ONLY) {
7429
5/8
✓ Branch 0 taken 839598 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 839596 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22 times.
✓ Branch 5 taken 839574 times.
✓ Branch 6 taken 22 times.
✗ Branch 7 not taken.
839597 DBUG_PRINT("info", ("skip_temporary is set"));
7430 839596 return false;
7431 }
7432
7433
1/2
✓ Branch 0 taken 18319568 times.
✗ Branch 1 not taken.
18319474 TABLE *table = find_temporary_table(thd, tl);
7434
7435 // Access to temporary tables is disallowed in XA transactions in
7436 // xa_detach_on_prepare=ON mode.
7437
2/2
✓ Branch 0 taken 304932 times.
✓ Branch 1 taken 17962261 times.
18267193 if ((tl->open_type == OT_TEMPORARY_ONLY ||
7438
3/4
✓ Branch 0 taken 304945 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 357343 times.
✓ Branch 3 taken 33 times.
662308 (table && table->s->tmp_table != NO_TMP_TABLE)) &&
7439
4/4
✓ Branch 0 taken 18267193 times.
✓ Branch 1 taken 52375 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 18319620 times.
36944137 is_xa_tran_detached_on_prepare(thd) &&
7440
3/4
✓ Branch 0 taken 357343 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 357339 times.
357343 thd->get_transaction()->xid_state()->check_in_xa(false)) {
7441
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 my_error(ER_XA_TEMP_TABLE, MYF(0));
7442 4 return true;
7443 }
7444
7445
2/2
✓ Branch 0 taken 18013431 times.
✓ Branch 1 taken 306189 times.
18319620 if (!table) {
7446
2/2
✓ Branch 0 taken 51458 times.
✓ Branch 1 taken 17961973 times.
18013431 if (tl->open_type == OT_TEMPORARY_ONLY &&
7447
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51458 times.
51458 tl->open_strategy == TABLE_LIST::OPEN_NORMAL) {
7448 my_error(ER_NO_SUCH_TABLE, MYF(0), tl->db, tl->table_name);
7449 return true;
7450 }
7451 18013431 return false;
7452 }
7453
7454
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 306188 times.
306189 if (tl->partition_names) {
7455 /* Partitioned temporary tables is not supported. */
7456
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 assert(!table->part_info);
7457
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_PARTITION_CLAUSE_ON_NONPARTITIONED, MYF(0));
7458 1 return true;
7459 }
7460
7461
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 306165 times.
306188 if (table->query_id) {
7462 /*
7463 We're trying to use the same temporary table twice in a query.
7464 Right now we don't support this because a temporary table is always
7465 represented by only one TABLE object in THD, and it can not be
7466 cloned. Emit an error for an unsupported behaviour.
7467 */
7468
7469
3/8
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 23 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
23 DBUG_PRINT("error", ("query_id: %lu server_id: %u pseudo_thread_id: %lu",
7470 (ulong)table->query_id, (uint)thd->server_id,
7471 (ulong)thd->variables.pseudo_thread_id));
7472
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
7473 23 return true;
7474 }
7475
7476 306165 table->query_id = thd->query_id;
7477 306165 thd->thread_specific_used = true;
7478
7479 306165 tl->set_updatable(); // It is not derived table nor non-updatable VIEW.
7480 305889 tl->set_insertable();
7481
7482
1/2
✓ Branch 0 taken 305889 times.
✗ Branch 1 not taken.
305889 table->reset();
7483
1/2
✓ Branch 0 taken 305889 times.
✗ Branch 1 not taken.
305889 table->init(thd, tl);
7484
7485
3/8
✓ Branch 0 taken 305890 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 305890 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 305890 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
305889 DBUG_PRINT("info", ("Using temporary table"));
7486 305890 return false;
7487 19158945 }
7488
7489 /**
7490 Pre-open temporary tables corresponding to table list elements.
7491
7492 @note One should finalize process of opening temporary tables
7493 by calling open_tables(). This function is responsible
7494 for table version checking and handling of merge tables.
7495
7496 @return Error status.
7497 @retval false On success. If a temporary tables exists for the
7498 given element, tl->table is set.
7499 @retval true On error. my_error() has been called.
7500 */
7501
7502 27854743 bool open_temporary_tables(THD *thd, TABLE_LIST *tl_list) {
7503 27854743 TABLE_LIST *first_not_own = thd->lex->first_not_own_table();
7504
1/2
✓ Branch 0 taken 27855230 times.
✗ Branch 1 not taken.
27855012 DBUG_TRACE;
7505
7506
4/4
✓ Branch 0 taken 19524759 times.
✓ Branch 1 taken 27854190 times.
✓ Branch 2 taken 19523357 times.
✓ Branch 3 taken 1402 times.
47378949 for (TABLE_LIST *tl = tl_list; tl && tl != first_not_own;
7507 19523719 tl = tl->next_global) {
7508 // Placeholder tables are processed during query execution
7509
2/2
✓ Branch 0 taken 19362026 times.
✓ Branch 1 taken 3527 times.
38888720 if (tl->is_view_or_derived() || tl->is_table_function() ||
7510
8/8
✓ Branch 0 taken 19365363 times.
✓ Branch 1 taken 158195 times.
✓ Branch 2 taken 19105372 times.
✓ Branch 3 taken 256654 times.
✓ Branch 4 taken 39 times.
✓ Branch 5 taken 19105194 times.
✓ Branch 6 taken 418415 times.
✓ Branch 7 taken 19105194 times.
38889111 tl->schema_table != nullptr || tl->is_recursive_reference())
7511 418415 continue;
7512
7513
3/4
✓ Branch 0 taken 19105332 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 19105304 times.
19105194 if (open_temporary_table(thd, tl)) return true;
7514 }
7515
7516 27855592 return false;
7517 27855620 }
7518
7519 /*
7520 Find a field by name in a view that uses merge algorithm.
7521
7522 SYNOPSIS
7523 find_field_in_view()
7524 thd thread handler
7525 table_list view to search for 'name'
7526 name name of field
7527 ref expression substituted in VIEW should be passed
7528 using this reference (return view_ref_found)
7529 register_tree_change true if ref is not stack variable and we
7530 need register changes in item tree
7531
7532 RETURN
7533 0 field is not found
7534 view_ref_found found value in VIEW (real result is in *ref)
7535 # pointer to field - only for schema table fields
7536 */
7537
7538 3052218 static Field *find_field_in_view(THD *thd, TABLE_LIST *table_list,
7539 const char *name, Item **ref,
7540 bool register_tree_change) {
7541
1/2
✓ Branch 0 taken 3052218 times.
✗ Branch 1 not taken.
3052218 DBUG_TRACE;
7542
3/8
✓ Branch 0 taken 3052218 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3052218 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3052218 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
3052218 DBUG_PRINT("enter", ("view: '%s', field name: '%s', ref %p",
7543 table_list->alias, name, ref));
7544 3052218 Field_iterator_view field_it;
7545
1/2
✓ Branch 0 taken 3052218 times.
✗ Branch 1 not taken.
3052218 field_it.set(table_list);
7546
7547
4/6
✓ Branch 0 taken 3052211 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 3052211 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3052211 times.
✗ Branch 5 not taken.
3052218 assert(table_list->schema_table_reformed ||
7548 (ref != nullptr && table_list->is_merged()));
7549
2/2
✓ Branch 0 taken 30057299 times.
✓ Branch 1 taken 2356 times.
30059654 for (; !field_it.end_of_fields(); field_it.next()) {
7550
4/6
✓ Branch 0 taken 30057299 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30057297 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3049861 times.
✓ Branch 5 taken 27007436 times.
30057299 if (!my_strcasecmp(system_charset_info, field_it.name(), name)) {
7551 Item *item;
7552
7553 {
7554 /*
7555 Use own arena for Prepared Statements or data will be freed after
7556 PREPARE.
7557 */
7558 Prepared_stmt_arena_holder ps_arena_holder(
7559
4/4
✓ Branch 0 taken 3047279 times.
✓ Branch 1 taken 2582 times.
✓ Branch 2 taken 2224617 times.
✓ Branch 3 taken 822662 times.
6097140 thd, register_tree_change &&
7560
1/2
✓ Branch 0 taken 3049861 times.
✗ Branch 1 not taken.
6097140 thd->stmt_arena->is_stmt_prepare_or_first_stmt_execute());
7561
7562 /*
7563 create_item() may, or may not create a new Item, depending on
7564 the column reference. See create_view_field() for details.
7565 */
7566
1/2
✓ Branch 0 taken 3049862 times.
✗ Branch 1 not taken.
3049861 item = field_it.create_item(thd);
7567
7568
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3049862 times.
3049862 if (!item) return nullptr;
7569
1/2
✓ Branch 0 taken 3049862 times.
✗ Branch 1 not taken.
3049862 }
7570
7571 /*
7572 *ref != NULL means that *ref contains the item that we need to
7573 replace. If the item was aliased by the user, set the alias to
7574 the replacing item.
7575 We need to set alias on both ref itself and on ref real item.
7576 */
7577
6/6
✓ Branch 0 taken 3047280 times.
✓ Branch 1 taken 2582 times.
✓ Branch 2 taken 529712 times.
✓ Branch 3 taken 2517568 times.
✓ Branch 4 taken 529712 times.
✓ Branch 5 taken 2520150 times.
3049862 if (*ref && !(*ref)->item_name.is_autogenerated()) {
7578 529712 item->item_name = (*ref)->item_name;
7579
1/2
✓ Branch 0 taken 529712 times.
✗ Branch 1 not taken.
529712 item->real_item()->item_name = (*ref)->item_name;
7580 }
7581 3049862 *ref = item;
7582 // WL#6570 remove-after-qa
7583
3/4
✓ Branch 0 taken 2224629 times.
✓ Branch 1 taken 825233 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2224629 times.
3049862 assert(thd->stmt_arena->is_regular() || !thd->lex->is_exec_started());
7584
7585 3049862 return view_ref_found;
7586 }
7587 }
7588 2356 return nullptr;
7589 3052218 }
7590
7591 /**
7592 Find field by name in a NATURAL/USING join table reference.
7593
7594 @param thd thread handler
7595 @param table_ref table reference to search
7596 @param name name of field
7597 @param [in,out] ref if 'name' is resolved to a view field, ref is
7598 set to point to the found view field
7599 @param register_tree_change true if ref is not stack variable and we
7600 need register changes in item tree
7601 @param [out] actual_table The original table reference where the field
7602 belongs - differs from 'table_list' only for
7603 NATURAL/USING joins
7604
7605 DESCRIPTION
7606 Search for a field among the result fields of a NATURAL/USING join.
7607 Notice that this procedure is called only for non-qualified field
7608 names. In the case of qualified fields, we search directly the base
7609 tables of a natural join.
7610
7611 Sometimes when a field is found, it is checked for privileges according to
7612 THD::want_privilege and marked according to THD::mark_used_columns.
7613 But it is unclear when, so caller generally has to do the same.
7614
7615 RETURN
7616 NULL if the field was not found
7617 WRONG_GRANT if no access rights to the found field
7618 # Pointer to the found Field
7619 */
7620
7621 35943 static Field *find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref,
7622 const char *name, Item **ref,
7623 bool register_tree_change,
7624 TABLE_LIST **actual_table) {
7625
1/2
✓ Branch 0 taken 35943 times.
✗ Branch 1 not taken.
35943 List_iterator_fast<Natural_join_column> field_it(*(table_ref->join_columns));
7626 Natural_join_column *nj_col, *curr_nj_col;
7627 35943 Field *found_field = nullptr;
7628
1/2
✓ Branch 0 taken 35943 times.
✗ Branch 1 not taken.
35943 DBUG_TRACE;
7629
3/8
✓ Branch 0 taken 35943 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 35943 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 35943 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
35943 DBUG_PRINT("enter", ("field name: '%s', ref %p", name, ref));
7630
2/4
✓ Branch 0 taken 35943 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 35943 times.
✗ Branch 3 not taken.
35943 assert(table_ref->is_natural_join && table_ref->join_columns);
7631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35943 times.
35943 assert(*actual_table == nullptr);
7632
7633
2/2
✓ Branch 0 taken 1150140 times.
✓ Branch 1 taken 35936 times.
1186076 for (nj_col = nullptr, curr_nj_col = field_it++; curr_nj_col;
7634 1150133 curr_nj_col = field_it++) {
7635
4/6
✓ Branch 0 taken 1150140 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1150140 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 31537 times.
✓ Branch 5 taken 1118603 times.
1150140 if (!my_strcasecmp(system_charset_info, curr_nj_col->name(), name)) {
7636
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 31530 times.
31537 if (nj_col) {
7637
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 my_error(ER_NON_UNIQ_ERROR, MYF(0), name, thd->where);
7638 7 return nullptr;
7639 }
7640 31530 nj_col = curr_nj_col;
7641 }
7642 }
7643
2/2
✓ Branch 0 taken 4413 times.
✓ Branch 1 taken 31523 times.
35936 if (!nj_col) return nullptr;
7644
7645
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 31508 times.
31523 if (nj_col->view_field) {
7646 Item *item;
7647
7648 {
7649
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 Prepared_stmt_arena_holder ps_arena_holder(thd, register_tree_change);
7650
7651 /*
7652 create_item() may, or may not create a new Item, depending on the
7653 column reference. See create_view_field() for details.
7654 */
7655
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 item = nj_col->create_item(thd);
7656
7657
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (!item) return nullptr;
7658
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 }
7659
7660 /*
7661 *ref != NULL means that *ref contains the item that we need to
7662 replace. If the item was aliased by the user, set the alias to
7663 the replacing item.
7664 We need to set alias on both ref itself and on ref real item.
7665 */
7666
3/6
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 15 times.
15 if (*ref && !(*ref)->item_name.is_autogenerated()) {
7667 item->item_name = (*ref)->item_name;
7668 item->real_item()->item_name = (*ref)->item_name;
7669 }
7670
7671
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 assert(nj_col->table_field == nullptr);
7672
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (nj_col->table_ref->schema_table_reformed) {
7673 /*
7674 Translation table items are always Item_fields and fixed
7675 already('mysql_schema_table' function). So we can return
7676 ->field. It is used only for 'show & where' commands.
7677 */
7678 return ((Item_field *)(nj_col->view_field->item))->field;
7679 }
7680 15 *ref = item;
7681 // WL#6570 remove-after-qa
7682
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15 assert(thd->stmt_arena->is_regular() || !thd->lex->is_exec_started());
7683 15 found_field = view_ref_found;
7684 } else {
7685 /* This is a base table. */
7686
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31508 times.
31508 assert(nj_col->view_field == nullptr);
7687 /*
7688 This fix_fields is not necessary (initially this item is fixed by
7689 the Item_field constructor; after reopen_tables the Item_func_eq
7690 calls fix_fields on that item), it's just a check during table
7691 reopening for columns that was dropped by the concurrent connection.
7692 */
7693
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 31508 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 31508 times.
31508 if (!nj_col->table_field->fixed &&
7694 nj_col->table_field->fix_fields(thd, (Item **)&nj_col->table_field)) {
7695 DBUG_PRINT("info",
7696 ("column '%s' was dropped by the concurrent connection",
7697 nj_col->table_field->item_name.ptr()));
7698 return nullptr;
7699 }
7700
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31508 times.
31508 assert(nj_col->table_ref->table == nj_col->table_field->field->table);
7701 31508 found_field = nj_col->table_field->field;
7702 }
7703
7704 31523 *actual_table = nj_col->table_ref;
7705
7706 31523 return found_field;
7707 35943 }
7708
7709 /**
7710 Find field by name in a base table.
7711
7712 No privileges are checked, and the column is not marked in read_set/write_set.
7713
7714 @param table table where to search for the field
7715 @param name name of field
7716 @param allow_rowid do allow finding of "_rowid" field?
7717 @param[out] field_index_ptr position in field list (used to speedup
7718 lookup for fields in prepared tables)
7719
7720 @retval NULL field is not found
7721 @retval != NULL pointer to field
7722 */
7723
7724 64086417 Field *find_field_in_table(TABLE *table, const char *name, bool allow_rowid,
7725 uint *field_index_ptr) {
7726
1/2
✓ Branch 0 taken 64086605 times.
✗ Branch 1 not taken.
64086417 DBUG_TRACE;
7727
5/8
✓ Branch 0 taken 64086523 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64086516 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 718 times.
✓ Branch 5 taken 64085798 times.
✓ Branch 6 taken 726 times.
✗ Branch 7 not taken.
64086605 DBUG_PRINT("enter", ("table: '%s', field name: '%s'", table->alias, name));
7728
7729 64086524 Field **field_ptr = nullptr, *field;
7730
7731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64086524 times.
64086524 if (!(field_ptr = table->field)) return nullptr;
7732
2/2
✓ Branch 0 taken 365232696 times.
✓ Branch 1 taken 256321 times.
365489017 for (; *field_ptr; ++field_ptr) {
7733 // NOTE: This should probably be strncollsp() instead of my_strcasecmp();
7734 // in particular, Ñ != N for my_strcasecmp(), which is not according to the
7735 // usual ai_ci rules. However, changing it would risk breaking existing
7736 // table definitions (which don't distinguish between N and Ñ), so we can
7737 // only do this when actually changing the system collation.
7738
3/4
✓ Branch 0 taken 365233280 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 63830787 times.
✓ Branch 3 taken 301402493 times.
365232696 if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
7739 63830787 break;
7740 }
7741
7742
4/4
✓ Branch 0 taken 64086656 times.
✓ Branch 1 taken 452 times.
✓ Branch 2 taken 63830794 times.
✓ Branch 3 taken 255862 times.
64087108 if (field_ptr && *field_ptr) {
7743 63830794 *field_index_ptr = field_ptr - table->field;
7744 63830794 field = *field_ptr;
7745 } else {
7746
7/8
✓ Branch 0 taken 114038 times.
✓ Branch 1 taken 142276 times.
✓ Branch 2 taken 114038 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 114028 times.
✓ Branch 6 taken 255849 times.
✓ Branch 7 taken 465 times.
256324 if (!allow_rowid || my_strcasecmp(system_charset_info, name, "_rowid") ||
7747
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 table->s->rowid_field_offset == 0)
7748 255849 return (Field *)nullptr;
7749 465 field = table->field[table->s->rowid_field_offset - 1];
7750 }
7751
7752 63831259 return field;
7753 64087108 }
7754
7755 /**
7756 Find field in a table reference.
7757
7758 @param thd thread handler
7759 @param table_list table reference to search
7760 @param name name of field
7761 @param length length of field name
7762 @param item_name name of item if it will be created (VIEW)
7763 @param db_name optional database name that qualifies the field
7764 @param table_name optional table name that qualifies the field
7765 @param[in,out] ref if 'name' is resolved to a view field, ref
7766 is set to point to the found view field
7767 @param want_privilege privileges to check for column
7768 = 0: no privilege checking is needed
7769 @param allow_rowid do allow finding of "_rowid" field?
7770 @param field_index_ptr position in field list (used to
7771 speedup lookup for fields in prepared tables)
7772 @param register_tree_change TRUE if ref is not stack variable and we
7773 need register changes in item tree
7774 @param[out] actual_table the original table reference where the field
7775 belongs - differs from 'table_list' only for
7776 NATURAL_USING joins.
7777
7778 Find a field in a table reference depending on the type of table
7779 reference. There are three types of table references with respect
7780 to the representation of their result columns:
7781 - an array of Field_translator objects for MERGE views and some
7782 information_schema tables,
7783 - an array of Field objects (and possibly a name hash) for stored
7784 tables,
7785 - a list of Natural_join_column objects for NATURAL/USING joins.
7786 This procedure detects the type of the table reference 'table_list'
7787 and calls the corresponding search routine.
7788
7789 The function checks column-level privileges for the found field
7790 according to argument want_privilege.
7791
7792 The function marks the column in corresponding table's read set or
7793 write set according to THD::mark_used_columns.
7794
7795 @retval NULL field is not found
7796 @retval view_ref_found found value in VIEW (real result is in *ref)
7797 @retval otherwise pointer to field
7798 */
7799
7800 217216412 Field *find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
7801 const char *name, size_t length,
7802 const char *item_name, const char *db_name,
7803 const char *table_name, Item **ref,
7804 ulong want_privilege, bool allow_rowid,
7805 uint *field_index_ptr, bool register_tree_change,
7806 TABLE_LIST **actual_table) {
7807 Field *fld;
7808
1/2
✓ Branch 0 taken 217217293 times.
✗ Branch 1 not taken.
217216412 DBUG_TRACE;
7809
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 217217293 times.
217217293 assert(table_list->alias);
7810
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 217217293 times.
217217293 assert(name);
7811
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 217217293 times.
217217293 assert(item_name);
7812
5/8
✓ Branch 0 taken 217217010 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 217216438 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 938 times.
✓ Branch 5 taken 217215500 times.
✓ Branch 6 taken 1223 times.
✗ Branch 7 not taken.
217217293 DBUG_PRINT("enter", ("table: '%s' field name: '%s' item name: '%s' ref %p",
7813 table_list->alias, name, item_name, ref));
7814
7815 /*
7816 Check that the table and database that qualify the current field name
7817 are the same as the table reference we are going to search for the field.
7818
7819 Exclude from the test below nested joins because the columns in a
7820 nested join generally originate from different tables. Nested joins
7821 also have no table name, except when a nested join is a merge view
7822 or an information schema table.
7823
7824 We include explicitly table references with a 'field_translation' table,
7825 because if there are views over natural joins we don't want to search
7826 inside the view, but we want to search directly in the view columns
7827 which are represented as a 'field_translation'.
7828
7829 TODO: Ensure that table_name, db_name and tables->db always points to
7830 something !
7831 */
7832 217216763 if (/* Exclude nested joins. */
7833 220519521 (!table_list->nested_join ||
7834 /* Include merge views and information schema tables. */
7835
4/4
✓ Branch 0 taken 3059694 times.
✓ Branch 1 taken 243104 times.
✓ Branch 2 taken 183272009 times.
✓ Branch 3 taken 33701610 times.
217216723 table_list->field_translation) &&
7836 /*
7837 Test if the field qualifiers match the table reference we plan
7838 to search.
7839 */
7840
5/6
✓ Branch 0 taken 3302798 times.
✓ Branch 1 taken 213913925 times.
✓ Branch 2 taken 183272552 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 149891001 times.
✓ Branch 5 taken 67325762 times.
617706038 table_name && table_name[0] &&
7841
5/6
✓ Branch 0 taken 183272592 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33381805 times.
✓ Branch 3 taken 149890787 times.
✓ Branch 4 taken 1441139 times.
✓ Branch 5 taken 31940666 times.
183272552 (my_strcasecmp(table_alias_charset, table_list->alias, table_name) ||
7842
6/8
✓ Branch 0 taken 1441139 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1441140 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1441135 times.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 174 times.
✓ Branch 7 taken 1440961 times.
2882274 (db_name && db_name[0] && table_list->db && table_list->db[0] &&
7843 1441135 (table_list->schema_table
7844
3/4
✓ Branch 0 taken 27360 times.
✓ Branch 1 taken 1413775 times.
✓ Branch 2 taken 27360 times.
✗ Branch 3 not taken.
1441135 ? my_strcasecmp(system_charset_info, db_name, table_list->db)
7845 1413775 : strcmp(db_name, table_list->db)))))
7846 149891001 return nullptr;
7847
7848 67325762 *actual_table = nullptr;
7849
7850
2/2
✓ Branch 0 taken 3052218 times.
✓ Branch 1 taken 64273544 times.
67325762 if (table_list->field_translation) {
7851 /* 'table_list' is a view or an information schema table. */
7852
3/4
✓ Branch 0 taken 3052218 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3049862 times.
✓ Branch 3 taken 2356 times.
3052218 if ((fld = find_field_in_view(thd, table_list, name, ref,
7853 register_tree_change)))
7854 3049862 *actual_table = table_list;
7855
2/2
✓ Branch 0 taken 64030492 times.
✓ Branch 1 taken 243052 times.
64273544 } else if (!table_list->nested_join) {
7856 /* 'table_list' is a stored table. */
7857
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 64030492 times.
64030492 assert(table_list->table);
7858
3/4
✓ Branch 0 taken 64030630 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 63774818 times.
✓ Branch 3 taken 255812 times.
64030492 if ((fld = find_field_in_table(table_list->table, name, allow_rowid,
7859 field_index_ptr)))
7860 63774818 *actual_table = table_list;
7861 } else {
7862 /*
7863 'table_list' is a NATURAL/USING join, or an operand of such join that
7864 is a nested join itself.
7865
7866 If the field name we search for is qualified, then search for the field
7867 in the table references used by NATURAL/USING the join.
7868 */
7869
3/4
✓ Branch 0 taken 207161 times.
✓ Branch 1 taken 35891 times.
✓ Branch 2 taken 207161 times.
✗ Branch 3 not taken.
243052 if (table_name && table_name[0]) {
7870
7/12
✓ Branch 0 taken 207161 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 207161 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 371975 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 191914 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 399075 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 371975 times.
✓ Branch 11 taken 27100 times.
399075 for (TABLE_LIST *table : table_list->nested_join->join_list) {
7871
3/4
✓ Branch 0 taken 371975 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 180061 times.
✓ Branch 3 taken 191914 times.
371975 if ((fld = find_field_in_table_ref(
7872 thd, table, name, length, item_name, db_name, table_name, ref,
7873 want_privilege, allow_rowid, field_index_ptr,
7874 register_tree_change, actual_table)))
7875 180061 return fld;
7876 }
7877 27100 return nullptr;
7878 }
7879 /*
7880 Non-qualified field, search directly in the result columns of the
7881 natural join. The condition of the outer IF is true for the top-most
7882 natural join, thus if the field is not qualified, we will search
7883 directly the top-most NATURAL/USING join.
7884 */
7885
1/2
✓ Branch 0 taken 35943 times.
✗ Branch 1 not taken.
35891 fld = find_field_in_natural_join(thd, table_list, name, ref,
7886 register_tree_change, actual_table);
7887 }
7888
7889
2/2
✓ Branch 0 taken 66856146 times.
✓ Branch 1 taken 262645 times.
67118791 if (fld) {
7890 // Check if there are sufficient privileges to the found field.
7891
2/2
✓ Branch 0 taken 16291338 times.
✓ Branch 1 taken 50564808 times.
66856146 if (want_privilege) {
7892
2/2
✓ Branch 0 taken 13513405 times.
✓ Branch 1 taken 2777933 times.
16291338 if (fld != view_ref_found) {
7893
3/4
✓ Branch 0 taken 13513402 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 13513363 times.
13513405 if (check_column_grant_in_table_ref(thd, *actual_table, name, length,
7894 want_privilege))
7895 39 return WRONG_GRANT;
7896 } else {
7897
3/6
✓ Branch 0 taken 2777937 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2777937 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2777937 times.
✗ Branch 5 not taken.
2777933 assert(ref && *ref && (*ref)->fixed);
7898
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2777937 times.
2777937 assert(*actual_table == (down_cast<Item_ident *>(*ref))->cached_table);
7899
7900 2777937 Column_privilege_tracker tracker(thd, want_privilege);
7901
3/4
✓ Branch 0 taken 2777935 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 2777915 times.
2777937 if ((*ref)->walk(&Item::check_column_privileges, enum_walk::PREFIX,
7902 (uchar *)thd))
7903 20 return WRONG_GRANT;
7904
2/2
✓ Branch 0 taken 2777915 times.
✓ Branch 1 taken 20 times.
2777935 }
7905 }
7906
7907 /*
7908 Get read_set correct for this field so that the handler knows that
7909 this field is involved in the query and gets retrieved.
7910 */
7911
2/2
✓ Branch 0 taken 3049854 times.
✓ Branch 1 taken 63806232 times.
66856086 if (fld == view_ref_found) {
7912 3049854 Mark_field mf(thd->mark_used_columns);
7913
1/2
✓ Branch 0 taken 3049857 times.
✗ Branch 1 not taken.
3049854 (*ref)->walk(&Item::mark_field_in_map, enum_walk::SUBQUERY_POSTFIX,
7914 (uchar *)&mf);
7915 } else // surely fld != NULL (see outer if())
7916
1/2
✓ Branch 0 taken 63806240 times.
✗ Branch 1 not taken.
63806232 fld->table->mark_column_used(fld, thd->mark_used_columns);
7917 }
7918 67118742 return fld;
7919 217216963 }
7920
7921 /*
7922 Find field in table, no side effects, only purpose is to check for field
7923 in table object and get reference to the field if found.
7924
7925 SYNOPSIS
7926 find_field_in_table_sef()
7927
7928 table table where to find
7929 name Name of field searched for
7930
7931 RETURN
7932 0 field is not found
7933 # pointer to field
7934 */
7935
7936 4790 Field *find_field_in_table_sef(TABLE *table, const char *name) {
7937 4790 Field **field_ptr = nullptr;
7938
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4790 times.
4790 if (!(field_ptr = table->field)) return nullptr;
7939
2/2
✓ Branch 0 taken 7652 times.
✓ Branch 1 taken 9 times.
7661 for (; *field_ptr; ++field_ptr) {
7940 // NOTE: See comment on the same call in find_field_in_table().
7941
2/2
✓ Branch 0 taken 4781 times.
✓ Branch 1 taken 2871 times.
7652 if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
7942 4781 break;
7943 }
7944
1/2
✓ Branch 0 taken 4790 times.
✗ Branch 1 not taken.
4790 if (field_ptr)
7945 4790 return *field_ptr;
7946 else
7947 return (Field *)nullptr;
7948 }
7949
7950 /*
7951 Find field in table list.
7952
7953 SYNOPSIS
7954 find_field_in_tables()
7955 thd pointer to current thread structure
7956 item field item that should be found
7957 first_table list of tables to be searched for item
7958 last_table end of the list of tables to search for item. If NULL
7959 then search to the end of the list 'first_table'.
7960 ref if 'item' is resolved to a view field, ref is set to
7961 point to the found view field
7962 report_error Degree of error reporting:
7963 - IGNORE_ERRORS then do not report any error
7964 - IGNORE_EXCEPT_NON_UNIQUE report only non-unique
7965 fields, suppress all other errors
7966 - REPORT_EXCEPT_NON_UNIQUE report all other errors
7967 except when non-unique fields were found
7968 - REPORT_ALL_ERRORS
7969 want_privilege column privileges to check
7970 = 0: no need to check privileges
7971 register_tree_change true if ref is not a stack variable and we
7972 to need register changes in item tree
7973
7974 RETURN VALUES
7975 0 If error: the found field is not unique, or there are
7976 no sufficient access privileges for the found field,
7977 or the field is qualified with non-existing table.
7978 not_found_field The function was called with report_error ==
7979 (IGNORE_ERRORS || IGNORE_EXCEPT_NON_UNIQUE) and a
7980 field was not found.
7981 view_ref_found View field is found, item passed through ref parameter
7982 found field If a item was resolved to some field
7983 */
7984
7985 66980157 Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *first_table,
7986 TABLE_LIST *last_table, Item **ref,
7987 find_item_error_report_type report_error,
7988 ulong want_privilege, bool register_tree_change) {
7989 66980157 Field *found = nullptr;
7990 66980157 const char *db = item->db_name;
7991 66980157 const char *table_name = item->table_name;
7992 66980157 const char *name = item->field_name;
7993 66980157 size_t length = strlen(name);
7994 uint field_index;
7995 char name_buff[NAME_LEN + 1];
7996 TABLE_LIST *actual_table;
7997 bool allow_rowid;
7998
7999
4/4
✓ Branch 0 taken 33410049 times.
✓ Branch 1 taken 33570108 times.
✓ Branch 2 taken 128 times.
✓ Branch 3 taken 33409921 times.
66980157 if (!table_name || !table_name[0]) {
8000 33570236 table_name = nullptr; // For easier test
8001 33570236 db = nullptr;
8002 }
8003
8004
6/6
✓ Branch 0 taken 33570298 times.
✓ Branch 1 taken 33409859 times.
✓ Branch 2 taken 33569041 times.
✓ Branch 3 taken 1257 times.
✓ Branch 4 taken 33435027 times.
✓ Branch 5 taken 134014 times.
66980157 allow_rowid = table_name || (first_table && !first_table->next_local);
8005
8006
2/2
✓ Branch 0 taken 16866 times.
✓ Branch 1 taken 66963291 times.
66980157 if (item->cached_table) {
8007 /*
8008 This shortcut is used by prepared statements. We assume that
8009 TABLE_LIST *first_table is not changed during query execution (which
8010 is true for all queries except RENAME but luckily RENAME doesn't
8011 use fields...) so we can rely on reusing pointer to its member.
8012 With this optimization we also miss case when addition of one more
8013 field makes some prepared query ambiguous and so erroneous, but we
8014 accept this trade off.
8015 */
8016 16866 TABLE_LIST *table_ref = item->cached_table;
8017
8018 /*
8019 @todo WL#6570 - is this reasonable???
8020 Also refactor this code to replace "cached_table" with "table_ref" -
8021 as there is no longer need for more than one resolving, hence
8022 no "caching" as well.
8023 */
8024
3/4
✓ Branch 0 taken 16866 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16862 times.
✓ Branch 3 taken 4 times.
16866 if (item->type() == Item::FIELD_ITEM)
8025 16862 field_index = down_cast<Item_field *>(item)->field_index;
8026
8027 /*
8028 The condition (table_ref->view == NULL) ensures that we will call
8029 find_field_in_table even in the case of information schema tables
8030 when table_ref->field_translation != NULL.
8031 */
8032
8033
6/6
✓ Branch 0 taken 16807 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 6902 times.
✓ Branch 3 taken 9905 times.
✓ Branch 4 taken 6902 times.
✓ Branch 5 taken 9964 times.
16866 if (table_ref->table && !table_ref->is_view()) {
8034
1/2
✓ Branch 0 taken 6902 times.
✗ Branch 1 not taken.
6902 found = find_field_in_table(table_ref->table, name, true, &field_index);
8035 // Check if there are sufficient privileges to the found field.
8036
3/6
✓ Branch 0 taken 6902 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6902 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6902 times.
13804 if (found && want_privilege &&
8037
2/4
✓ Branch 0 taken 6902 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6902 times.
6902 check_column_grant_in_table_ref(thd, table_ref, name, length,
8038 want_privilege))
8039 found = WRONG_GRANT;
8040
2/4
✓ Branch 0 taken 6902 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6902 times.
✗ Branch 3 not taken.
6902 if (found && found != WRONG_GRANT)
8041
1/2
✓ Branch 0 taken 6926 times.
✗ Branch 1 not taken.
6902 table_ref->table->mark_column_used(found, thd->mark_used_columns);
8042 } else {
8043
1/2
✓ Branch 0 taken 9964 times.
✗ Branch 1 not taken.
9964 found = find_field_in_table_ref(thd, table_ref, name, length,
8044 item->item_name.ptr(), nullptr, nullptr,
8045 ref, want_privilege, true, &field_index,
8046 register_tree_change, &actual_table);
8047 }
8048
2/2
✓ Branch 0 taken 16866 times.
✓ Branch 1 taken 24 times.
16890 if (found) {
8049
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16866 times.
16866 if (found == WRONG_GRANT) return nullptr;
8050
8051 // @todo WL#6570 move this assignment to a more strategic place?
8052
3/4
✓ Branch 0 taken 16866 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16862 times.
✓ Branch 3 taken 4 times.
16866 if (item->type() == Item::FIELD_ITEM)
8053 16862 down_cast<Item_field *>(item)->field_index = field_index;
8054
8055 16866 return found;
8056 }
8057 }
8058
8059
9/10
✓ Branch 0 taken 1441183 times.
✓ Branch 1 taken 65522132 times.
✓ Branch 2 taken 1293742 times.
✓ Branch 3 taken 147441 times.
✓ Branch 4 taken 1293742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 51589 times.
✓ Branch 7 taken 1242153 times.
✓ Branch 8 taken 199030 times.
✓ Branch 9 taken 66764285 times.
66963315 if (db && (lower_case_table_names || is_infoschema_db(db, strlen(db)))) {
8060 /*
8061 convert database to lower case for comparison.
8062 We can't do this in Item_field as this would change the
8063 'name' of the item which may be used in the select list
8064
8065 The 'information_schema' name is treated as case-insensitive
8066 identifier when specified in FROM clause even in
8067 lower_case_table_names=0. We lowercase the 'information_schema' name
8068 below to treat it as case-insensitive even when it is referred in WHERE
8069 or SELECT clause.
8070 */
8071
1/2
✓ Branch 0 taken 199030 times.
✗ Branch 1 not taken.
199030 strmake(name_buff, db, sizeof(name_buff) - 1);
8072
1/2
✓ Branch 0 taken 199030 times.
✗ Branch 1 not taken.
199030 my_casedn_str(files_charset_info, name_buff);
8073 199030 db = name_buff;
8074 }
8075
8076
4/4
✓ Branch 0 taken 66961457 times.
✓ Branch 1 taken 1858 times.
✓ Branch 2 taken 66869126 times.
✓ Branch 3 taken 92331 times.
66963315 if (first_table && first_table->query_block &&
8077
2/2
✓ Branch 0 taken 4427 times.
✓ Branch 1 taken 66864699 times.
66869126 first_table->query_block->end_lateral_table)
8078 4427 last_table = first_table->query_block->end_lateral_table;
8079
2/2
✓ Branch 0 taken 4487321 times.
✓ Branch 1 taken 62471567 times.
66958888 else if (last_table)
8080 4487321 last_table = last_table->next_name_resolution_table;
8081
8082 TABLE_LIST *cur_table;
8083
8084
2/2
✓ Branch 0 taken 216834145 times.
✓ Branch 1 taken 65521445 times.
282355590 for (cur_table = first_table; cur_table != last_table;
8085 215392275 cur_table = cur_table->next_name_resolution_table) {
8086
1/2
✓ Branch 0 taken 216835002 times.
✗ Branch 1 not taken.
216834145 Field *cur_field = find_field_in_table_ref(
8087 thd, cur_table, name, length, item->item_name.ptr(), db, table_name,
8088 ref, want_privilege, allow_rowid, &field_index, register_tree_change,
8089 &actual_table);
8090
9/10
✓ Branch 0 taken 149989178 times.
✓ Branch 1 taken 66845824 times.
✓ Branch 2 taken 149989155 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 149989149 times.
✓ Branch 5 taken 6 times.
✓ Branch 6 taken 59 times.
✓ Branch 7 taken 216834914 times.
✓ Branch 8 taken 65 times.
✓ Branch 9 taken 216834914 times.
216835002 if ((cur_field == nullptr && thd->is_error()) || cur_field == WRONG_GRANT)
8091 65 return nullptr;
8092
8093
2/2
✓ Branch 0 taken 66845871 times.
✓ Branch 1 taken 149989043 times.
216834914 if (cur_field) {
8094 /*
8095 Store the original table of the field, which may be different from
8096 cur_table in the case of NATURAL/USING join.
8097 */
8098 66845871 item->cached_table =
8099
4/4
✓ Branch 0 taken 66733011 times.
✓ Branch 1 taken 112860 times.
✓ Branch 2 taken 66731186 times.
✓ Branch 3 taken 1825 times.
66845871 (!actual_table->cacheable_table || found) ? nullptr : actual_table;
8100
8101 // @todo WL#6570 move this assignment to a more strategic place?
8102
2/4
✓ Branch 0 taken 66845733 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 66845751 times.
✗ Branch 3 not taken.
66845871 if (item->type() == Item::FIELD_ITEM)
8103 66845751 down_cast<Item_field *>(item)->field_index = field_index;
8104
8105
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66845661 times.
66845661 assert(thd->where);
8106 /*
8107 If we found a fully qualified field we return it directly as it can't
8108 have duplicates.
8109 */
8110
2/2
✓ Branch 0 taken 1440601 times.
✓ Branch 1 taken 65405060 times.
66845661 if (db) return cur_field;
8111
8112
2/2
✓ Branch 0 taken 1828 times.
✓ Branch 1 taken 65403232 times.
65405060 if (found) {
8113
3/4
✓ Branch 0 taken 1828 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 1819 times.
1828 if (report_error == REPORT_ALL_ERRORS ||
8114 report_error == IGNORE_EXCEPT_NON_UNIQUE)
8115
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
10 my_error(ER_NON_UNIQ_ERROR, MYF(0),
8116
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 table_name ? item->full_name() : name, thd->where);
8117 1828 return (Field *)nullptr;
8118 }
8119 65403232 found = cur_field;
8120 }
8121 }
8122
8123
2/2
✓ Branch 0 taken 65401464 times.
✓ Branch 1 taken 119981 times.
65521445 if (found) return found;
8124
8125 /*
8126 If the field was qualified and there were no tables to search, issue
8127 an error that an unknown table was given. The situation is detected
8128 as follows: if there were no tables we wouldn't go through the loop
8129 and cur_table wouldn't be updated by the loop increment part, so it
8130 will be equal to the first table.
8131 @todo revisit this logic. If the first table is a table function or lateral
8132 derived table and contains an inner column reference in it which is not
8133 found, cur_table==first_table, even though there _were_ tables to search.
8134 */
8135
6/6
✓ Branch 0 taken 11980 times.
✓ Branch 1 taken 108001 times.
✓ Branch 2 taken 701 times.
✓ Branch 3 taken 11279 times.
✓ Branch 4 taken 422 times.
✓ Branch 5 taken 279 times.
119981 if (table_name && (cur_table == first_table) &&
8136
1/2
✓ Branch 0 taken 493 times.
✗ Branch 1 not taken.
422 (report_error == REPORT_ALL_ERRORS ||
8137 report_error == REPORT_EXCEPT_NON_UNIQUE)) {
8138 char buff[NAME_LEN * 2 + 2];
8139
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 772 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
772 if (db && db[0]) {
8140 strxnmov(buff, sizeof(buff) - 1, db, ".", table_name, NullS);
8141 table_name = buff;
8142 }
8143
1/2
✓ Branch 0 taken 279 times.
✗ Branch 1 not taken.
772 my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where);
8144 279 } else {
8145
3/4
✓ Branch 0 taken 117823 times.
✓ Branch 1 taken 1386 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 117823 times.
119209 if (report_error == REPORT_ALL_ERRORS ||
8146 report_error == REPORT_EXCEPT_NON_UNIQUE) {
8147 /* We now know that this column does not exist in any table_list
8148 of the query. If user does not have grant, then we should throw
8149 error stating 'access denied'. If user does have right then we can
8150 give proper error like column does not exist. Following is check
8151 to see if column has wrong grants and avoids error like 'bad field'
8152 and throw column access error.
8153 */
8154
5/6
✓ Branch 0 taken 999 times.
✓ Branch 1 taken 387 times.
✓ Branch 2 taken 882 times.
✓ Branch 3 taken 117 times.
✓ Branch 4 taken 1386 times.
✗ Branch 5 not taken.
2268 if (!first_table || (want_privilege == 0) ||
8155
2/4
✓ Branch 0 taken 882 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 882 times.
✗ Branch 3 not taken.
882 !check_column_grant_in_table_ref(thd, first_table, name, length,
8156 want_privilege))
8157
2/4
✓ Branch 0 taken 1386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1386 times.
✗ Branch 3 not taken.
1386 my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), thd->where);
8158 } else
8159 117823 found = not_found_field;
8160 }
8161 119488 return found;
8162 }
8163
8164 /*
8165 Find Item in list of items (find_field_in_tables analog)
8166
8167 TODO
8168 is it better return only counter?
8169
8170 SYNOPSIS
8171 find_item_in_list()
8172 find Item to find
8173 items List of items
8174 counter To return number of found item
8175 report_error
8176 REPORT_ALL_ERRORS report errors, return 0 if error
8177 REPORT_EXCEPT_NOT_FOUND Do not report 'not found' error and
8178 return not_found_item, report other errors,
8179 return 0
8180 IGNORE_ERRORS Do not report errors, return 0 if error
8181 resolution Set to the resolution type if the item is found
8182 (it says whether the item is resolved
8183 against an alias name,
8184 or as a field name without alias,
8185 or as a field hidden by alias,
8186 or ignoring alias)
8187
8188 RETURN VALUES
8189 0 Item is not found or item is not unique,
8190 error message is reported
8191 not_found_item Function was called with
8192 report_error == REPORT_EXCEPT_NOT_FOUND and
8193 item was not found. No error message was reported
8194 found field
8195 */
8196
8197 /* Special Item pointer to serve as a return value from find_item_in_list(). */
8198 Item **not_found_item = (Item **)0x1;
8199
8200 1360945 Item **find_item_in_list(THD *thd, Item *find, mem_root_deque<Item *> *items,
8201 uint *counter,
8202 find_item_error_report_type report_error,
8203 enum_resolution_type *resolution) {
8204 1360945 Item **found = nullptr, **found_unaliased = nullptr;
8205 1360945 const char *db_name = nullptr;
8206 1360945 const char *field_name = nullptr;
8207 1360945 const char *table_name = nullptr;
8208 1360945 bool found_unaliased_non_uniq = false;
8209 /*
8210 true if the item that we search for is a valid name reference
8211 (and not an item that happens to have a name).
8212 */
8213 1360945 bool is_ref_by_name = false;
8214 1360945 uint unaliased_counter = 0;
8215
8216 1360945 *resolution = NOT_RESOLVED;
8217
8218 1360945 is_ref_by_name =
8219
4/4
✓ Branch 0 taken 145932 times.
✓ Branch 1 taken 1215013 times.
✓ Branch 2 taken 25323 times.
✓ Branch 3 taken 120609 times.
1360945 (find->type() == Item::FIELD_ITEM || find->type() == Item::REF_ITEM);
8220
2/2
✓ Branch 0 taken 1240336 times.
✓ Branch 1 taken 120609 times.
1360945 if (is_ref_by_name) {
8221 1240336 field_name = ((Item_ident *)find)->field_name;
8222 1240336 table_name = ((Item_ident *)find)->table_name;
8223 1240336 db_name = ((Item_ident *)find)->db_name;
8224 }
8225
8226 1360945 int i = 0;
8227
2/4
✓ Branch 0 taken 1360945 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1360945 times.
✗ Branch 3 not taken.
1360945 for (auto it = VisibleFields(*items).begin();
8228
6/10
✓ Branch 0 taken 11410265 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12771210 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12771210 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12771210 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 11732460 times.
✓ Branch 9 taken 1038750 times.
12771210 it != VisibleFields(*items).end(); ++it, ++i) {
8229
1/2
✓ Branch 0 taken 11732460 times.
✗ Branch 1 not taken.
11732460 Item *item = *it;
8230
8/10
✓ Branch 0 taken 11187943 times.
✓ Branch 1 taken 544517 times.
✓ Branch 2 taken 11187943 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11187943 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 8717888 times.
✓ Branch 7 taken 2470055 times.
✓ Branch 8 taken 8717888 times.
✓ Branch 9 taken 3014572 times.
11732460 if (field_name && item->real_item()->type() == Item::FIELD_ITEM) {
8231 8717888 Item_ident *item_field = (Item_ident *)item;
8232
8233 /*
8234 In case of group_concat() with ORDER BY condition in the QUERY
8235 item_field can be field of temporary table without item name
8236 (if this field created from expression argument of group_concat()),
8237 => we have to check presence of name before compare
8238 */
8239
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8717888 times.
8717888 if (!item_field->item_name.is_set()) continue;
8240
8241
2/2
✓ Branch 0 taken 697603 times.
✓ Branch 1 taken 8020285 times.
8717888 if (table_name) {
8242 /*
8243 If table name is specified we should find field 'field_name' in
8244 table 'table_name'. According to SQL-standard we should ignore
8245 aliases in this case.
8246
8247 Since we should NOT prefer fields from the select list over
8248 other fields from the tables participating in this select in
8249 case of ambiguity we have to do extra check outside this function.
8250
8251 We use strcmp for table names and database names as these may be
8252 case sensitive. In cases where they are not case sensitive, they
8253 are always in lower case.
8254
8255 item_field->field_name and item_field->table_name can be 0x0 if
8256 item is not fix_field()'ed yet.
8257 */
8258
1/2
✓ Branch 0 taken 697603 times.
✗ Branch 1 not taken.
697603 if (item_field->field_name && item_field->table_name &&
8259
3/4
✓ Branch 0 taken 697603 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 51470 times.
✓ Branch 3 taken 646133 times.
697603 !my_strcasecmp(system_charset_info, item_field->field_name,
8260 51470 field_name) &&
8261
3/4
✓ Branch 0 taken 51470 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46715 times.
✓ Branch 3 taken 4755 times.
51470 !my_strcasecmp(table_alias_charset, item_field->table_name,
8262
5/6
✓ Branch 0 taken 697603 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18612 times.
✓ Branch 3 taken 28103 times.
✓ Branch 4 taken 46715 times.
✓ Branch 5 taken 650888 times.
1413818 table_name) &&
8263 18612 (!db_name ||
8264
2/4
✓ Branch 0 taken 18612 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18612 times.
✗ Branch 3 not taken.
18612 (item_field->db_name && !strcmp(item_field->db_name, db_name)))) {
8265
2/2
✓ Branch 0 taken 103 times.
✓ Branch 1 taken 46612 times.
46715 if (found_unaliased) {
8266
2/4
✓ Branch 0 taken 103 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103 times.
✗ Branch 3 not taken.
103 if ((*found_unaliased)->eq(item, false)) continue;
8267 /*
8268 Two matching fields in select list.
8269 We already can bail out because we are searching through
8270 unaliased names only and will have duplicate error anyway.
8271 */
8272 if (report_error != IGNORE_ERRORS)
8273 my_error(ER_NON_UNIQ_ERROR, MYF(0), find->full_name(),
8274 thd->where);
8275 12 return (Item **)nullptr;
8276 }
8277
1/2
✓ Branch 0 taken 46612 times.
✗ Branch 1 not taken.
46612 found_unaliased = &*it;
8278 46612 unaliased_counter = i;
8279 46612 *resolution = RESOLVED_IGNORING_ALIAS;
8280
2/2
✓ Branch 0 taken 18612 times.
✓ Branch 1 taken 28000 times.
46612 if (db_name) break; // Perfect match
8281 }
8282 } else {
8283
1/2
✓ Branch 0 taken 8020285 times.
✗ Branch 1 not taken.
8020285 int fname_cmp = my_strcasecmp(system_charset_info,
8284 item_field->field_name, field_name);
8285
3/4
✓ Branch 0 taken 8020285 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 837688 times.
✓ Branch 3 taken 7182597 times.
8020285 if (item_field->item_name.eq_safe(field_name)) {
8286 /*
8287 If table name was not given we should scan through aliases
8288 and non-aliased fields first. We are also checking unaliased
8289 name of the field in then next else-if, to be able to find
8290 instantly field (hidden by alias) if no suitable alias or
8291 non-aliased field was found.
8292 */
8293
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 837584 times.
837688 if (found) {
8294
3/4
✓ Branch 0 taken 104 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 92 times.
✓ Branch 3 taken 12 times.
104 if ((*found)->eq(item, false)) continue; // Same field twice
8295
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (report_error != IGNORE_ERRORS)
8296
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 my_error(ER_NON_UNIQ_ERROR, MYF(0), find->full_name(),
8297 thd->where);
8298 12 return (Item **)nullptr;
8299 }
8300
1/2
✓ Branch 0 taken 837584 times.
✗ Branch 1 not taken.
837584 found = &*it;
8301 837584 *counter = i;
8302 837584 *resolution =
8303
2/2
✓ Branch 0 taken 1037 times.
✓ Branch 1 taken 836547 times.
837584 fname_cmp ? RESOLVED_AGAINST_ALIAS : RESOLVED_WITH_NO_ALIAS;
8304
2/2
✓ Branch 0 taken 39702 times.
✓ Branch 1 taken 7142895 times.
7182597 } else if (!fname_cmp) {
8305 /*
8306 We will use non-aliased field or react on such ambiguities only if
8307 we won't be able to find aliased field.
8308 Again if we have ambiguity with field outside of select list
8309 we should prefer fields from select list.
8310 */
8311
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 39696 times.
39702 if (found_unaliased) {
8312
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if ((*found_unaliased)->eq(item, false))
8313 continue; // Same field twice
8314 6 found_unaliased_non_uniq = true;
8315 }
8316
1/2
✓ Branch 0 taken 39702 times.
✗ Branch 1 not taken.
39702 found_unaliased = &*it;
8317 39702 unaliased_counter = i;
8318 }
8319 }
8320
2/2
✓ Branch 0 taken 2685472 times.
✓ Branch 1 taken 329100 times.
3014572 } else if (!table_name) {
8321
7/8
✓ Branch 0 taken 2140998 times.
✓ Branch 1 taken 544474 times.
✓ Branch 2 taken 2140998 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 233684 times.
✓ Branch 5 taken 1907314 times.
✓ Branch 6 taken 233684 times.
✓ Branch 7 taken 2451788 times.
2685472 if (is_ref_by_name && item->item_name.eq_safe(find->item_name)) {
8322
1/2
✓ Branch 0 taken 233684 times.
✗ Branch 1 not taken.
233684 found = &*it;
8323 233684 *counter = i;
8324 233684 *resolution = RESOLVED_AGAINST_ALIAS;
8325 233684 break;
8326
3/4
✓ Branch 0 taken 2451788 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69819 times.
✓ Branch 3 taken 2381969 times.
2451788 } else if (find->eq(item, false)) {
8327
1/2
✓ Branch 0 taken 69819 times.
✗ Branch 1 not taken.
69819 found = &*it;
8328 69819 *counter = i;
8329 69819 *resolution = RESOLVED_IGNORING_ALIAS;
8330 69819 break;
8331 }
8332
6/8
✓ Branch 0 taken 329101 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 329101 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24915 times.
✓ Branch 5 taken 304186 times.
✓ Branch 6 taken 24907 times.
✓ Branch 7 taken 304193 times.
354015 } else if (table_name && item->type() == Item::REF_ITEM &&
8333
3/4
✓ Branch 0 taken 24915 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24907 times.
✓ Branch 3 taken 8 times.
24915 ((Item_ref *)item)->ref_type() == Item_ref::VIEW_REF) {
8334 /*
8335 TODO:Here we process prefixed view references only. What we should
8336 really do is process all types of Item_refs. But this will currently
8337 lead to a clash with the way references to outer SELECTs (from the
8338 HAVING clause) are handled in e.g. :
8339 SELECT 1 FROM t1 AS t1_o GROUP BY a
8340 HAVING (SELECT t1_o.a FROM t1 AS t1_i GROUP BY t1_i.a LIMIT 1).
8341 Processing all Item_refs here will cause t1_o.a to resolve to itself.
8342 We still need to process the special case of Item_view_ref
8343 because in the context of views they have the same meaning as
8344 Item_field for tables.
8345 */
8346 24907 Item_ident *item_ref = (Item_ident *)item;
8347
2/4
✓ Branch 0 taken 24907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
24979 if (item_ref->item_name.eq_safe(field_name) && item_ref->table_name &&
8348
3/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 68 times.
✓ Branch 3 taken 4 times.
72 !my_strcasecmp(table_alias_charset, item_ref->table_name,
8349
6/6
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 24835 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 33 times.
✓ Branch 4 taken 68 times.
✓ Branch 5 taken 24839 times.
25014 table_name) &&
8350 35 (!db_name ||
8351
2/4
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
35 (item_ref->db_name && !strcmp(item_ref->db_name, db_name)))) {
8352
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 found = &*it;
8353 68 *counter = i;
8354 68 *resolution = RESOLVED_IGNORING_ALIAS;
8355 68 break;
8356 }
8357 }
8358 }
8359
2/2
✓ Branch 0 taken 219792 times.
✓ Branch 1 taken 1141141 times.
1360933 if (!found) {
8360
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 219786 times.
219792 if (found_unaliased_non_uniq) {
8361
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (report_error != IGNORE_ERRORS)
8362 6 my_error(ER_NON_UNIQ_ERROR, MYF(0), find->full_name(), thd->where);
8363 6 return (Item **)nullptr;
8364 }
8365
2/2
✓ Branch 0 taken 86290 times.
✓ Branch 1 taken 133496 times.
219786 if (found_unaliased) {
8366 86290 found = found_unaliased;
8367 86290 *counter = unaliased_counter;
8368 86290 *resolution = RESOLVED_BEHIND_ALIAS;
8369 }
8370 }
8371
2/2
✓ Branch 0 taken 1227431 times.
✓ Branch 1 taken 133496 times.
1360927 if (found) return found;
8372
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 133496 times.
133496 if (report_error != REPORT_EXCEPT_NOT_FOUND) {
8373 if (report_error == REPORT_ALL_ERRORS)
8374 my_error(ER_BAD_FIELD_ERROR, MYF(0), find->full_name(), thd->where);
8375 return (Item **)nullptr;
8376 } else
8377 133496 return not_found_item;
8378 }
8379
8380 /*
8381 Test if a string is a member of a list of strings.
8382
8383 SYNOPSIS
8384 test_if_string_in_list()
8385 find the string to look for
8386 str_list a list of strings to be searched
8387
8388 DESCRIPTION
8389 Sequentially search a list of strings for a string, and test whether
8390 the list contains the same string.
8391
8392 RETURN
8393 true if find is in str_list
8394 false otherwise
8395 */
8396
8397 332741 static bool test_if_string_in_list(const char *find, List<String> *str_list) {
8398
1/2
✓ Branch 0 taken 332741 times.
✗ Branch 1 not taken.
332741 List_iterator<String> str_list_it(*str_list);
8399 String *curr_str;
8400 332741 size_t find_length = strlen(find);
8401
2/2
✓ Branch 0 taken 351810 times.
✓ Branch 1 taken 319973 times.
671783 while ((curr_str = str_list_it++)) {
8402
2/2
✓ Branch 0 taken 312736 times.
✓ Branch 1 taken 39074 times.
351810 if (find_length != curr_str->length()) continue;
8403
3/4
✓ Branch 0 taken 39074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12768 times.
✓ Branch 3 taken 26306 times.
39074 if (!my_strcasecmp(system_charset_info, find, curr_str->ptr())) return true;
8404 }
8405 319973 return false;
8406 }
8407
8408 /*
8409 Create a new name resolution context for an item so that it is
8410 being resolved in a specific table reference.
8411
8412 SYNOPSIS
8413 set_new_item_local_context()
8414 thd pointer to current thread
8415 item item for which new context is created and set
8416 table_ref table ref where an item showld be resolved
8417
8418 DESCRIPTION
8419 Create a new name resolution context for an item, so that the item
8420 is resolved only the supplied 'table_ref'.
8421
8422 RETURN
8423 false if all OK
8424 true otherwise
8425 */
8426
8427 29426 static bool set_new_item_local_context(THD *thd, Item_ident *item,
8428 TABLE_LIST *table_ref) {
8429 Name_resolution_context *context;
8430
3/6
✓ Branch 0 taken 29426 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29426 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 29426 times.
29426 if (!(context = new (thd->mem_root) Name_resolution_context))
8431 return true; /* purecov: inspected */
8432 29426 context->init();
8433 29426 context->first_name_resolution_table = context->last_name_resolution_table =
8434 table_ref;
8435 29426 context->query_block = table_ref->query_block;
8436 29426 context->next_context = table_ref->query_block->first_context;
8437 29426 table_ref->query_block->first_context = context;
8438 29426 item->context = context;
8439 29426 return false;
8440 }
8441
8442 /*
8443 Find and mark the common columns of two table references.
8444
8445 SYNOPSIS
8446 mark_common_columns()
8447 thd [in] current thread
8448 table_ref_1 [in] the first (left) join operand
8449 table_ref_2 [in] the second (right) join operand
8450 using_fields [in] if the join is JOIN...USING - the join columns,
8451 if NATURAL join, then NULL
8452 found_using_fields [out] number of fields from the USING clause that were
8453 found among the common fields
8454
8455 DESCRIPTION
8456 The procedure finds the common columns of two relations (either
8457 tables or intermediate join results), and adds an equi-join condition
8458 to the ON clause of 'table_ref_2' for each pair of matching columns.
8459 If some of table_ref_XXX represents a base table or view, then we
8460 create new 'Natural_join_column' instances for each column
8461 reference and store them in the 'join_columns' of the table
8462 reference.
8463
8464 IMPLEMENTATION
8465 The procedure assumes that store_natural_using_join_columns() was
8466 called for the previous level of NATURAL/USING joins.
8467
8468 RETURN
8469 true error when some common column is non-unique, or out of memory
8470 false OK
8471 */
8472
8473 13334 static bool mark_common_columns(THD *thd, TABLE_LIST *table_ref_1,
8474 TABLE_LIST *table_ref_2,
8475 List<String> *using_fields,
8476 uint *found_using_fields) {
8477
2/4
✓ Branch 0 taken 13334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13334 times.
✗ Branch 3 not taken.
13334 Field_iterator_table_ref it_1, it_2;
8478 Natural_join_column *nj_col_1, *nj_col_2;
8479 13334 bool first_outer_loop = true;
8480 13334 List<Field> fields;
8481 /*
8482 Leaf table references to which new natural join columns are added
8483 if the leaves are != NULL.
8484 */
8485 13334 TABLE_LIST *leaf_1 =
8486
4/4
✓ Branch 0 taken 3791 times.
✓ Branch 1 taken 9543 times.
✓ Branch 2 taken 3641 times.
✓ Branch 3 taken 150 times.
13334 (table_ref_1->nested_join && !table_ref_1->is_natural_join) ? nullptr
8487 : table_ref_1;
8488 13334 TABLE_LIST *leaf_2 =
8489
4/4
✓ Branch 0 taken 660 times.
✓ Branch 1 taken 12674 times.
✓ Branch 2 taken 493 times.
✓ Branch 3 taken 167 times.
13334 (table_ref_2->nested_join && !table_ref_2->is_natural_join) ? nullptr
8490 : table_ref_2;
8491
8492
1/2
✓ Branch 0 taken 13334 times.
✗ Branch 1 not taken.
13334 DBUG_TRACE;
8493
3/8
✓ Branch 0 taken 13334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13334 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 13334 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
13334 DBUG_PRINT("info", ("operand_1: %s operand_2: %s", table_ref_1->alias,
8494 table_ref_2->alias));
8495
8496 /*
8497 Hidden columns for functional indexes don't participate in NATURAL /
8498 USING JOIN and invisible columns don't participate in NATURAL JOIN.
8499 (we need to go through get_or_create_column_ref() before calling
8500 this method).
8501 */
8502 13154471 auto is_non_participant_column = [using_fields](Field *field) {
8503
3/4
✓ Branch 0 taken 6576294 times.
✓ Branch 1 taken 1883 times.
✓ Branch 2 taken 6576294 times.
✗ Branch 3 not taken.
19730765 return (field != nullptr &&
8504
2/2
✓ Branch 0 taken 7177 times.
✓ Branch 1 taken 6569117 times.
13152588 (field->is_field_for_functional_index() ||
8505
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7177 times.
6585354 ((using_fields == nullptr) && field->is_hidden_by_user())));
8506 13334 };
8507
8508
1/2
✓ Branch 0 taken 13334 times.
✗ Branch 1 not taken.
13334 Prepared_stmt_arena_holder ps_arena_holder(thd);
8509
8510 13334 *found_using_fields = 0;
8511
8512
5/8
✓ Branch 0 taken 13334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 334653 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 347987 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 334693 times.
✓ Branch 7 taken 13294 times.
347987 for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next()) {
8513 334693 bool found = false;
8514 const char *field_name_1;
8515 /* true if field_name_1 is a member of using_fields */
8516 bool is_using_column_1;
8517
2/4
✓ Branch 0 taken 334693 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 334693 times.
334693 if (!(nj_col_1 = it_1.get_or_create_column_ref(thd, leaf_1))) return true;
8518
2/4
✓ Branch 0 taken 334693 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 334693 times.
334693 if (is_non_participant_column(it_1.field())) continue;
8519
8520
1/2
✓ Branch 0 taken 334693 times.
✗ Branch 1 not taken.
334693 field_name_1 = nj_col_1->name();
8521 334693 is_using_column_1 =
8522
5/6
✓ Branch 0 taken 332004 times.
✓ Branch 1 taken 2689 times.
✓ Branch 2 taken 332004 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12289 times.
✓ Branch 5 taken 319715 times.
334693 using_fields && test_if_string_in_list(field_name_1, using_fields);
8523
3/14
✓ Branch 0 taken 334693 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 334693 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 334693 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
334693 DBUG_PRINT("info", ("field_name_1=%s.%s",
8524 nj_col_1->table_name() ? nj_col_1->table_name() : "",
8525 field_name_1));
8526
8527 /*
8528 Find a field with the same name in table_ref_2.
8529
8530 Note that for the second loop, it_2.set() will iterate over
8531 table_ref_2->join_columns and not generate any new elements or
8532 lists.
8533 */
8534 334693 nj_col_2 = nullptr;
8535
5/8
✓ Branch 0 taken 334693 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6243444 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6578137 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6243484 times.
✓ Branch 7 taken 334653 times.
6578137 for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next()) {
8536 Natural_join_column *cur_nj_col_2;
8537 const char *cur_field_name_2;
8538
2/4
✓ Branch 0 taken 6243484 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6243484 times.
6243484 if (!(cur_nj_col_2 = it_2.get_or_create_column_ref(thd, leaf_2)))
8539 return true;
8540
2/4
✓ Branch 0 taken 6243484 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6243484 times.
6243484 if (is_non_participant_column(it_2.field())) continue;
8541
8542
1/2
✓ Branch 0 taken 6243484 times.
✗ Branch 1 not taken.
6243484 cur_field_name_2 = cur_nj_col_2->name();
8543
3/14
✓ Branch 0 taken 6243484 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6243484 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 6243484 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
6243484 DBUG_PRINT("info",
8544 ("cur_field_name_2=%s.%s",
8545 cur_nj_col_2->table_name() ? cur_nj_col_2->table_name() : "",
8546 cur_field_name_2));
8547
8548 /*
8549 Compare the two columns and check for duplicate common fields.
8550 A common field is duplicate either if it was already found in
8551 table_ref_2 (then found == true), or if a field in table_ref_2
8552 was already matched by some previous field in table_ref_1
8553 (then cur_nj_col_2->is_common == true).
8554 Note that it is too early to check the columns outside of the
8555 USING list for ambiguity because they are not actually "referenced"
8556 here. These columns must be checked only on unqualified reference
8557 by name (e.g. in SELECT list).
8558 */
8559
3/4
✓ Branch 0 taken 6243484 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76342 times.
✓ Branch 3 taken 6167142 times.
6243484 if (!my_strcasecmp(system_charset_info, field_name_1, cur_field_name_2)) {
8560
3/8
✓ Branch 0 taken 76342 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76342 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 76342 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
76342 DBUG_PRINT("info", ("match c1.is_common=%d", nj_col_1->is_common));
8561
4/4
✓ Branch 0 taken 76306 times.
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 505 times.
✓ Branch 3 taken 75801 times.
76342 if (cur_nj_col_2->is_common ||
8562
3/4
✓ Branch 0 taken 505 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 501 times.
505 (found && (!using_fields || is_using_column_1))) {
8563
1/2
✓ Branch 0 taken 40 times.
✗ Branch 1 not taken.
40 my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, thd->where);
8564 40 return true;
8565 }
8566 76302 nj_col_2 = cur_nj_col_2;
8567 76302 found = true;
8568 }
8569 }
8570
4/4
✓ Branch 0 taken 13567 times.
✓ Branch 1 taken 321086 times.
✓ Branch 2 taken 13164 times.
✓ Branch 3 taken 403 times.
334653 if (first_outer_loop && leaf_2) {
8571 /*
8572 Make sure that the next inner loop "knows" that all columns
8573 are materialized already.
8574 */
8575 13164 leaf_2->is_join_columns_complete = true;
8576 13164 first_outer_loop = false;
8577 }
8578
2/2
✓ Branch 0 taken 258856 times.
✓ Branch 1 taken 75797 times.
334653 if (!found) continue; // No matching field
8579
8580 /*
8581 field_1 and field_2 have the same names. Check if they are in the USING
8582 clause (if present), mark them as common fields, and add a new
8583 equi-join condition to the ON clause.
8584 */
8585
5/6
✓ Branch 0 taken 75797 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 73333 times.
✓ Branch 3 taken 2464 times.
✓ Branch 4 taken 12249 times.
✓ Branch 5 taken 61084 times.
75797 if (nj_col_2 && (!using_fields || is_using_column_1)) {
8586
1/2
✓ Branch 0 taken 14713 times.
✗ Branch 1 not taken.
14713 Item *item_1 = nj_col_1->create_item(thd);
8587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14713 times.
14713 if (!item_1) return true;
8588
1/2
✓ Branch 0 taken 14713 times.
✗ Branch 1 not taken.
14713 Item *item_2 = nj_col_2->create_item(thd);
8589
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14713 times.
14713 if (!item_2) return true;
8590
8591
1/2
✓ Branch 0 taken 14713 times.
✗ Branch 1 not taken.
14713 Field *field_1 = nj_col_1->field();
8592
1/2
✓ Branch 0 taken 14713 times.
✗ Branch 1 not taken.
14713 Field *field_2 = nj_col_2->field();
8593 Item_ident *item_ident_1, *item_ident_2;
8594 Item_func_eq *eq_cond;
8595
1/2
✓ Branch 0 taken 14713 times.
✗ Branch 1 not taken.
14713 fields.push_back(field_1);
8596
1/2
✓ Branch 0 taken 14713 times.
✗ Branch 1 not taken.
14713 fields.push_back(field_2);
8597
8598 /*
8599 The created items must be of sub-classes of Item_ident.
8600 */
8601
5/8
✓ Branch 0 taken 14713 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76 times.
✓ Branch 3 taken 14637 times.
✓ Branch 4 taken 76 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 76 times.
14713 assert(item_1->type() == Item::FIELD_ITEM ||
8602 item_1->type() == Item::REF_ITEM);
8603
5/8
✓ Branch 0 taken 14713 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197 times.
✓ Branch 3 taken 14516 times.
✓ Branch 4 taken 197 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 197 times.
14713 assert(item_2->type() == Item::FIELD_ITEM ||
8604 item_2->type() == Item::REF_ITEM);
8605
8606 /*
8607 We need to cast item_1,2 to Item_ident, because we need to hook name
8608 resolution contexts specific to each item.
8609 */
8610 14713 item_ident_1 = (Item_ident *)item_1;
8611 14713 item_ident_2 = (Item_ident *)item_2;
8612 /*
8613 Create and hook special name resolution contexts to each item in the
8614 new join condition . We need this to both speed-up subsequent name
8615 resolution of these items, and to enable proper name resolution of
8616 the items during the execute phase of PS.
8617 */
8618
3/6
✓ Branch 0 taken 14713 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14713 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14713 times.
29426 if (set_new_item_local_context(thd, item_ident_1, nj_col_1->table_ref) ||
8619
2/4
✓ Branch 0 taken 14713 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14713 times.
14713 set_new_item_local_context(thd, item_ident_2, nj_col_2->table_ref))
8620 return true;
8621
8622
3/6
✓ Branch 0 taken 14713 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14713 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14713 times.
14713 if (!(eq_cond = new Item_func_eq(item_ident_1, item_ident_2)))
8623 return true; // Out of memory.
8624
8625 /*
8626 Add the new equi-join condition to the ON clause. Notice that
8627 fix_fields() is applied to all ON conditions in setup_conds()
8628 so we don't do it here.
8629 */
8630
1/2
✓ Branch 0 taken 14713 times.
✗ Branch 1 not taken.
14713 add_join_on(table_ref_2, eq_cond);
8631
8632 14713 nj_col_1->is_common = nj_col_2->is_common = true;
8633
3/24
✓ Branch 0 taken 14713 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14713 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14713 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
14713 DBUG_PRINT("info", ("%s.%s and %s.%s are common",
8634 nj_col_1->table_name() ? nj_col_1->table_name() : "",
8635 nj_col_1->name(),
8636 nj_col_2->table_name() ? nj_col_2->table_name() : "",
8637 nj_col_2->name()));
8638
8639 // Mark fields in the read set
8640
2/2
✓ Branch 0 taken 14637 times.
✓ Branch 1 taken 76 times.
14713 if (field_1) {
8641
1/2
✓ Branch 0 taken 14637 times.
✗ Branch 1 not taken.
14637 nj_col_1->table_ref->table->mark_column_used(field_1,
8642 MARK_COLUMNS_READ);
8643 } else {
8644 76 Mark_field mf(MARK_COLUMNS_READ);
8645
1/2
✓ Branch 0 taken 76 times.
✗ Branch 1 not taken.
76 item_1->walk(&Item::mark_field_in_map, enum_walk::SUBQUERY_POSTFIX,
8646 (uchar *)&mf);
8647 }
8648
8649
2/2
✓ Branch 0 taken 14516 times.
✓ Branch 1 taken 197 times.
14713 if (field_2) {
8650
1/2
✓ Branch 0 taken 14516 times.
✗ Branch 1 not taken.
14516 nj_col_2->table_ref->table->mark_column_used(field_2,
8651 MARK_COLUMNS_READ);
8652 } else {
8653 197 Mark_field mf(MARK_COLUMNS_READ);
8654
1/2
✓ Branch 0 taken 197 times.
✗ Branch 1 not taken.
197 item_2->walk(&Item::mark_field_in_map, enum_walk::SUBQUERY_POSTFIX,
8655 (uchar *)&mf);
8656 }
8657
8658
2/2
✓ Branch 0 taken 12249 times.
✓ Branch 1 taken 2464 times.
14713 if (using_fields != nullptr) ++(*found_using_fields);
8659 }
8660 }
8661
8662
2/2
✓ Branch 0 taken 13180 times.
✓ Branch 1 taken 114 times.
13294 if (leaf_1) leaf_1->is_join_columns_complete = true;
8663
8664 /*
8665 Everything is OK.
8666 Notice that at this point there may be some column names in the USING
8667 clause that are not among the common columns. This is an SQL error and
8668 we check for this error in store_natural_using_join_columns() when
8669 (found_using_fields < length(join_using_fields)).
8670 */
8671 13294 return false;
8672 13334 }
8673
8674 /*
8675 Materialize and store the row type of NATURAL/USING join.
8676
8677 SYNOPSIS
8678 store_natural_using_join_columns()
8679 thd current thread
8680 natural_using_join the table reference of the NATURAL/USING join
8681 table_ref_1 the first (left) operand (of a NATURAL/USING join).
8682 table_ref_2 the second (right) operand (of a NATURAL/USING join).
8683 using_fields if the join is JOIN...USING - the join columns,
8684 if NATURAL join, then NULL
8685 found_using_fields number of fields from the USING clause that were
8686 found among the common fields
8687
8688 DESCRIPTION
8689 Iterate over the columns of both join operands and sort and store
8690 all columns into the 'join_columns' list of natural_using_join
8691 where the list is formed by three parts:
8692 part1: The coalesced columns of table_ref_1 and table_ref_2,
8693 sorted according to the column order of the first table.
8694 part2: The other columns of the first table, in the order in
8695 which they were defined in CREATE TABLE.
8696 part3: The other columns of the second table, in the order in
8697 which they were defined in CREATE TABLE.
8698 Time complexity - O(N1+N2), where Ni = length(table_ref_i).
8699
8700 IMPLEMENTATION
8701 The procedure assumes that mark_common_columns() has been called
8702 for the join that is being processed.
8703
8704 RETURN
8705 true error: Some common column is ambiguous
8706 false OK
8707 */
8708
8709 13294 static bool store_natural_using_join_columns(THD *thd,
8710 TABLE_LIST *natural_using_join,
8711 TABLE_LIST *table_ref_1,
8712 TABLE_LIST *table_ref_2,
8713 List<String> *using_fields,
8714 uint found_using_fields) {
8715
2/4
✓ Branch 0 taken 13294 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13294 times.
✗ Branch 3 not taken.
13294 Field_iterator_table_ref it_1, it_2;
8716 Natural_join_column *nj_col_1, *nj_col_2;
8717 List<Natural_join_column> *non_join_columns;
8718
1/2
✓ Branch 0 taken 13294 times.
✗ Branch 1 not taken.
13294 DBUG_TRACE;
8719
8720
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13294 times.
13294 assert(!natural_using_join->join_columns);
8721
8722
1/2
✓ Branch 0 taken 13294 times.
✗ Branch 1 not taken.
13294 Prepared_stmt_arena_holder ps_arena_holder(thd);
8723
8724
3/6
✓ Branch 0 taken 13294 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13294 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 13294 times.
26588 if (!(non_join_columns = new (thd->mem_root) List<Natural_join_column>) ||
8725
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13294 times.
13294 !(natural_using_join->join_columns =
8726
1/2
✓ Branch 0 taken 13294 times.
✗ Branch 1 not taken.
13294 new (thd->mem_root) List<Natural_join_column>))
8727 return true;
8728
8729 /* Append the columns of the first join operand. */
8730
5/8
✓ Branch 0 taken 13294 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 334617 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 347911 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 334617 times.
✓ Branch 7 taken 13294 times.
347911 for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next()) {
8731
1/2
✓ Branch 0 taken 334617 times.
✗ Branch 1 not taken.
334617 nj_col_1 = it_1.get_natural_column_ref();
8732
2/2
✓ Branch 0 taken 14677 times.
✓ Branch 1 taken 319940 times.
334617 if (nj_col_1->is_common) {
8733
1/2
✓ Branch 0 taken 14677 times.
✗ Branch 1 not taken.
14677 natural_using_join->join_columns->push_back(nj_col_1);
8734 /* Reset the common columns for the next call to mark_common_columns. */
8735 14677 nj_col_1->is_common = false;
8736 } else
8737
1/2
✓ Branch 0 taken 319940 times.
✗ Branch 1 not taken.
319940 non_join_columns->push_back(nj_col_1);
8738 }
8739
8740 /*
8741 Check that all columns in the USING clause are among the common
8742 columns. If this is not the case, report the first one that was
8743 not found in an error.
8744 */
8745
4/4
✓ Branch 0 taken 11129 times.
✓ Branch 1 taken 2165 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 11128 times.
13294 if (using_fields && found_using_fields < using_fields->elements) {
8746 String *using_field_name;
8747
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 List_iterator_fast<String> using_fields_it(*using_fields);
8748
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 while ((using_field_name = using_fields_it++)) {
8749
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 const char *using_field_name_ptr = using_field_name->c_ptr();
8750 List_iterator_fast<Natural_join_column> it(
8751
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 *(natural_using_join->join_columns));
8752 Natural_join_column *common_field;
8753
8754 for (;;) {
8755 /* If reached the end of fields, and none was found, report error. */
8756
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (!(common_field = it++)) {
8757
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
8758 thd->where);
8759 1 return true;
8760 }
8761 if (!my_strcasecmp(system_charset_info, common_field->name(),
8762 using_field_name_ptr))
8763 break; // Found match
8764 }
8765 }
8766 }
8767
8768 /* Append the non-equi-join columns of the second join operand. */
8769
5/8
✓ Branch 0 taken 13293 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 169162 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 182455 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 169162 times.
✓ Branch 7 taken 13293 times.
182455 for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next()) {
8770
1/2
✓ Branch 0 taken 169162 times.
✗ Branch 1 not taken.
169162 nj_col_2 = it_2.get_natural_column_ref();
8771
2/2
✓ Branch 0 taken 154485 times.
✓ Branch 1 taken 14677 times.
169162 if (!nj_col_2->is_common)
8772
1/2
✓ Branch 0 taken 154485 times.
✗ Branch 1 not taken.
154485 non_join_columns->push_back(nj_col_2);
8773 else {
8774 /* Reset the common columns for the next call to mark_common_columns. */
8775 14677 nj_col_2->is_common = false;
8776 }
8777 }
8778
8779
2/2
✓ Branch 0 taken 10084 times.
✓ Branch 1 taken 3209 times.
13293 if (non_join_columns->elements > 0)
8780
1/2
✓ Branch 0 taken 10084 times.
✗ Branch 1 not taken.
10084 natural_using_join->join_columns->concat(non_join_columns);
8781 13293 natural_using_join->is_join_columns_complete = true;
8782
8783 13293 return false;
8784 13294 }
8785
8786 /*
8787 Precompute and store the row types of the top-most NATURAL/USING joins.
8788
8789 SYNOPSIS
8790 store_top_level_join_columns()
8791 thd current thread
8792 table_ref nested join or table in a FROM clause
8793 left_neighbor neighbor table reference to the left of table_ref at the
8794 same level in the join tree
8795 right_neighbor neighbor table reference to the right of table_ref at the
8796 same level in the join tree
8797
8798 DESCRIPTION
8799 The procedure performs a post-order traversal of a nested join tree
8800 and materializes the row types of NATURAL/USING joins in a
8801 bottom-up manner until it reaches the TABLE_LIST elements that
8802 represent the top-most NATURAL/USING joins. The procedure should be
8803 applied to each element of Query_block::top_join_list (i.e. to each
8804 top-level element of the FROM clause).
8805
8806 IMPLEMENTATION
8807 Notice that the table references in the list nested_join->join_list
8808 are in reverse order, thus when we iterate over it, we are moving
8809 from the right to the left in the FROM clause.
8810
8811 RETURN
8812 true Error
8813 false OK
8814 */
8815
8816 2500362 static bool store_top_level_join_columns(THD *thd, TABLE_LIST *table_ref,
8817 TABLE_LIST *left_neighbor,
8818 TABLE_LIST *right_neighbor) {
8819
1/2
✓ Branch 0 taken 2500362 times.
✗ Branch 1 not taken.
2500362 DBUG_TRACE;
8820
8821
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2500362 times.
2500362 assert(!table_ref->nested_join->natural_join_processed);
8822
8823
1/2
✓ Branch 0 taken 2500362 times.
✗ Branch 1 not taken.
2500362 Prepared_stmt_arena_holder ps_arena_holder(thd);
8824
8825 /* Call the procedure recursively for each nested table reference. */
8826
4/8
✓ Branch 0 taken 2500362 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2500362 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2500362 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2500362 times.
✗ Branch 7 not taken.
2500362 if (table_ref->nested_join && !table_ref->nested_join->join_list.empty()) {
8827
1/2
✓ Branch 0 taken 2500362 times.
✗ Branch 1 not taken.
2500362 auto nested_it = table_ref->nested_join->join_list.begin();
8828
2/4
✓ Branch 0 taken 2500362 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2500362 times.
✗ Branch 3 not taken.
2500362 TABLE_LIST *same_level_left_neighbor = *nested_it++;
8829 2500362 TABLE_LIST *same_level_right_neighbor = nullptr;
8830 /* Left/right-most neighbors, possibly at higher levels in the join tree. */
8831 TABLE_LIST *real_left_neighbor, *real_right_neighbor;
8832
8833
2/2
✓ Branch 0 taken 4596212 times.
✓ Branch 1 taken 2500362 times.
7096574 while (same_level_left_neighbor) {
8834 4596212 TABLE_LIST *cur_table_ref = same_level_left_neighbor;
8835 4596212 same_level_left_neighbor =
8836
4/6
✓ Branch 0 taken 4596212 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4596212 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2500362 times.
✓ Branch 5 taken 2095850 times.
4596212 (nested_it == table_ref->nested_join->join_list.end()) ? nullptr
8837
2/4
✓ Branch 0 taken 2095850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2095850 times.
✗ Branch 3 not taken.
2095850 : *nested_it++;
8838 /*
8839 Pick the parent's left and right neighbors if there are no immediate
8840 neighbors at the same level.
8841 */
8842 4596212 real_left_neighbor =
8843
2/2
✓ Branch 0 taken 2095850 times.
✓ Branch 1 taken 2500362 times.
4596212 (same_level_left_neighbor) ? same_level_left_neighbor : left_neighbor;
8844 4596212 real_right_neighbor = (same_level_right_neighbor)
8845
2/2
✓ Branch 0 taken 2095850 times.
✓ Branch 1 taken 2500362 times.
4596212 ? same_level_right_neighbor
8846 : right_neighbor;
8847
8848 11230246 if (cur_table_ref->nested_join &&
8849
5/6
✓ Branch 0 taken 2037822 times.
✓ Branch 1 taken 2558390 times.
✓ Branch 2 taken 1635294 times.
✓ Branch 3 taken 402528 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4596212 times.
6231506 !cur_table_ref->nested_join->natural_join_processed &&
8850
2/4
✓ Branch 0 taken 1635294 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1635294 times.
1635294 store_top_level_join_columns(thd, cur_table_ref, real_left_neighbor,
8851 real_right_neighbor))
8852 return true;
8853 4596212 same_level_right_neighbor = cur_table_ref;
8854 }
8855 }
8856
8857 /*
8858 If this is a NATURAL/USING join, materialize its result columns and
8859 convert to a JOIN ... ON.
8860 */
8861
2/2
✓ Branch 0 taken 13334 times.
✓ Branch 1 taken 2487028 times.
2500362 if (table_ref->is_natural_join) {
8862
2/4
✓ Branch 0 taken 13334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13334 times.
✗ Branch 3 not taken.
13334 assert(table_ref->nested_join &&
8863 table_ref->nested_join->join_list.size() == 2);
8864
1/2
✓ Branch 0 taken 13334 times.
✗ Branch 1 not taken.
13334 auto operand_it = table_ref->nested_join->join_list.begin();
8865 /*
8866 Notice that the order of join operands depends on whether table_ref
8867 represents a LEFT or a RIGHT join. In a RIGHT join, the operands are
8868 in inverted order.
8869 */
8870
2/4
✓ Branch 0 taken 13334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13334 times.
✗ Branch 3 not taken.
13334 TABLE_LIST *table_ref_2 = *operand_it++; /* Second NATURAL join operand.*/
8871
2/4
✓ Branch 0 taken 13334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13334 times.
✗ Branch 3 not taken.
13334 TABLE_LIST *table_ref_1 = *operand_it++; /* First NATURAL join operand. */
8872 13334 List<String> *using_fields = table_ref->join_using_fields;
8873 uint found_using_fields;
8874
8875
3/4
✓ Branch 0 taken 13334 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40 times.
✓ Branch 3 taken 13294 times.
13334 if (mark_common_columns(thd, table_ref_1, table_ref_2, using_fields,
8876 &found_using_fields))
8877 41 return true;
8878
8879
3/4
✓ Branch 0 taken 13294 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 13293 times.
13294 if (store_natural_using_join_columns(thd, table_ref, table_ref_1,
8880 table_ref_2, using_fields,
8881 found_using_fields))
8882 1 return true;
8883
8884 /*
8885 Change NATURAL JOIN to JOIN ... ON. We do this for both operands
8886 because either one of them or the other is the one with the
8887 natural join flag because RIGHT joins are transformed into LEFT,
8888 and the two tables may be reordered.
8889 */
8890 13293 table_ref_1->natural_join = table_ref_2->natural_join = nullptr;
8891
8892 /* Add a true condition to outer joins that have no common columns. */
8893
6/6
✓ Branch 0 taken 8497 times.
✓ Branch 1 taken 4796 times.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 8453 times.
✓ Branch 4 taken 44 times.
✓ Branch 5 taken 13249 times.
13293 if (table_ref_2->outer_join && !table_ref_2->join_cond())
8894
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
88 table_ref_2->set_join_cond(new Item_func_true());
8895
8896 /* Change this table reference to become a leaf for name resolution. */
8897
2/2
✓ Branch 0 taken 626 times.
✓ Branch 1 taken 12667 times.
13293 if (left_neighbor) {
8898 TABLE_LIST *last_leaf_on_the_left;
8899
1/2
✓ Branch 0 taken 626 times.
✗ Branch 1 not taken.
626 last_leaf_on_the_left = left_neighbor->last_leaf_for_name_resolution();
8900 626 last_leaf_on_the_left->next_name_resolution_table = table_ref;
8901 }
8902
2/2
✓ Branch 0 taken 5481 times.
✓ Branch 1 taken 7812 times.
13293 if (right_neighbor) {
8903 TABLE_LIST *first_leaf_on_the_right;
8904 first_leaf_on_the_right =
8905
1/2
✓ Branch 0 taken 5481 times.
✗ Branch 1 not taken.
5481 right_neighbor->first_leaf_for_name_resolution();
8906 5481 table_ref->next_name_resolution_table = first_leaf_on_the_right;
8907 } else
8908 7812 table_ref->next_name_resolution_table = nullptr;
8909 }
8910
8911 2500321 table_ref->nested_join->natural_join_processed = true;
8912
8913 2500321 return false;
8914 2500362 }
8915
8916 /*
8917 Compute and store the row types of the top-most NATURAL/USING joins
8918 in a FROM clause.
8919
8920 SYNOPSIS
8921 setup_natural_join_row_types()
8922 thd current thread
8923 from_clause list of top-level table references in a FROM clause
8924
8925 DESCRIPTION
8926 Apply the procedure 'store_top_level_join_columns' to each of the
8927 top-level table references of the FROM clause. Adjust the list of tables
8928 for name resolution - context->first_name_resolution_table to the
8929 top-most, lef-most NATURAL/USING join.
8930
8931 IMPLEMENTATION
8932 Notice that the table references in 'from_clause' are in reverse
8933 order, thus when we iterate over it, we are moving from the right
8934 to the left in the FROM clause.
8935
8936 RETURN
8937 true Error
8938 false OK
8939 */
8940 927661 bool setup_natural_join_row_types(THD *thd,
8941 mem_root_deque<TABLE_LIST *> *from_clause,
8942 Name_resolution_context *context) {
8943
1/2
✓ Branch 0 taken 927661 times.
✗ Branch 1 not taken.
927661 DBUG_TRACE;
8944 927661 thd->where = "from clause";
8945
2/4
✓ Branch 0 taken 927661 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 927661 times.
927661 if (from_clause->empty())
8946 return false; /* We come here in the case of UNIONs. */
8947
8948
1/2
✓ Branch 0 taken 927661 times.
✗ Branch 1 not taken.
927661 auto table_ref_it = from_clause->begin();
8949 /* Table reference to the left of the current. */
8950
2/4
✓ Branch 0 taken 927661 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 927661 times.
✗ Branch 3 not taken.
927661 TABLE_LIST *left_neighbor = *table_ref_it++;
8951 /* Table reference to the right of the current. */
8952 927661 TABLE_LIST *right_neighbor = nullptr;
8953
8954 /* Note that tables in the list are in reversed order */
8955
2/2
✓ Branch 0 taken 1003371 times.
✓ Branch 1 taken 927620 times.
1930991 while (left_neighbor) {
8956 /* Current table reference. */
8957 1003371 TABLE_LIST *table_ref = left_neighbor;
8958 1003371 left_neighbor =
8959
6/10
✓ Branch 0 taken 1003371 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1003371 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 927661 times.
✓ Branch 5 taken 75710 times.
✓ Branch 6 taken 75710 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 75710 times.
✗ Branch 9 not taken.
1003371 (table_ref_it == from_clause->end()) ? nullptr : *table_ref_it++;
8960
8961 /*
8962 Do not redo work if already done:
8963 - for prepared statements and stored procedures,
8964 - if already processed inside a derived table/view.
8965 */
8966
2/2
✓ Branch 0 taken 865068 times.
✓ Branch 1 taken 138303 times.
1003371 if (table_ref->nested_join &&
8967
1/2
✓ Branch 0 taken 865068 times.
✗ Branch 1 not taken.
865068 !table_ref->nested_join->natural_join_processed) {
8968
3/4
✓ Branch 0 taken 865068 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
✓ Branch 3 taken 865027 times.
865068 if (store_top_level_join_columns(thd, table_ref, left_neighbor,
8969 right_neighbor))
8970 41 return true;
8971 }
8972
3/4
✓ Branch 0 taken 75710 times.
✓ Branch 1 taken 927620 times.
✓ Branch 2 taken 75710 times.
✗ Branch 3 not taken.
1003330 if (left_neighbor && context->query_block->first_execution) {
8973 75710 left_neighbor->next_name_resolution_table =
8974
1/2
✓ Branch 0 taken 75710 times.
✗ Branch 1 not taken.
75710 table_ref->first_leaf_for_name_resolution();
8975 }
8976 1003330 right_neighbor = table_ref;
8977 }
8978
8979 /*
8980 Store the top-most, left-most NATURAL/USING join, so that we start
8981 the search from that one instead of context->table_list. At this point
8982 right_neighbor points to the left-most top-level table reference in the
8983 FROM clause.
8984 */
8985
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 927620 times.
927620 assert(right_neighbor);
8986 927620 context->first_name_resolution_table =
8987
1/2
✓ Branch 0 taken 927620 times.
✗ Branch 1 not taken.
927620 right_neighbor->first_leaf_for_name_resolution();
8988
8989 927620 return false;
8990 927661 }
8991
8992 /**
8993 Resolve variable assignments from LEX object
8994
8995 @param thd Thread handler
8996 @param lex Lex object containing variable assignments
8997
8998 @returns false if success, true if error
8999
9000 @note
9001 set_entry() must be called before fix_fields() of the whole list of
9002 field items because:
9003
9004 1) the list of field items has same order as in the query, and the
9005 Item_func_get_user_var item may go before the Item_func_set_user_var:
9006
9007 @verbatim
9008 SELECT @a, @a := 10 FROM t;
9009 @endverbatim
9010
9011 2) The entry->update_query_id value controls constantness of
9012 Item_func_get_user_var items, so in presence of Item_func_set_user_var
9013 items we have to refresh their entries before fixing of
9014 Item_func_get_user_var items.
9015 */
9016
9017 3843 bool resolve_var_assignments(THD *thd, LEX *lex) {
9018
1/2
✓ Branch 0 taken 3843 times.
✗ Branch 1 not taken.
3843 List_iterator<Item_func_set_user_var> li(lex->set_var_list);
9019 Item_func_set_user_var *var;
9020
3/4
✓ Branch 0 taken 4825 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4825 times.
✓ Branch 3 taken 3843 times.
8668 while ((var = li++)) var->set_entry(thd, false);
9021
9022 3843 return false;
9023 }
9024
9025 /****************************************************************************
9026 ** Check that all given fields exists and fill struct with current data
9027 ****************************************************************************/
9028
9029 /**
9030 Resolve a list of expressions and setup appropriate data
9031
9032 @param thd thread handler
9033 @param want_privilege privilege representing desired operation.
9034 whether the expressions are selected, inserted
9035 or updated, or no operation is done.
9036 will also decide inclusion in read/write maps.
9037 @param allow_sum_func true if set operations are allowed in context.
9038 @param column_update if true, reject expressions that do not resolve
9039 to a base table column
9040 @param split_sum_funcs If true, Item::split_sum_func will add hidden
9041 items to "fields". See also description in its
9042 helper method Item::split_sum_func2.
9043 @param typed_items List of reference items for type derivation
9044 May be nullptr.
9045 @param[in,out] fields list of expressions, populated with resolved
9046 data about expressions.
9047 @param[out] ref_item_array filled in with references to items.
9048
9049 @retval false if success
9050 @retval true if error
9051
9052 @note The function checks updatability/insertability for the table before
9053 checking column privileges, for consistent error reporting.
9054 This has consequences for columns that are specified to be updated:
9055 The column is first resolved without privilege check.
9056 This check is followed by an updatablity/insertability check.
9057 Finally, a column privilege check is run, and the column is marked
9058 for update.
9059 */
9060
9061 30052730 bool setup_fields(THD *thd, ulong want_privilege, bool allow_sum_func,
9062 bool split_sum_funcs, bool column_update,
9063 const mem_root_deque<Item *> *typed_items,
9064 mem_root_deque<Item *> *fields,
9065 Ref_item_array ref_item_array) {
9066
1/2
✓ Branch 0 taken 30053409 times.
✗ Branch 1 not taken.
30052730 DBUG_TRACE;
9067
9068 30053409 Query_block *const select = thd->lex->current_query_block();
9069 30053347 const enum_mark_columns save_mark_used_columns = thd->mark_used_columns;
9070 30053347 nesting_map save_allow_sum_func = thd->lex->allow_sum_func;
9071 Column_privilege_tracker column_privilege(thd,
9072
2/2
✓ Branch 0 taken 5791111 times.
✓ Branch 1 taken 24262236 times.
30053347 column_update ? 0 : want_privilege);
9073
9074 // Function can only be used to set up one specific operation:
9075
7/8
✓ Branch 0 taken 29356139 times.
✓ Branch 1 taken 696901 times.
✓ Branch 2 taken 5804614 times.
✓ Branch 3 taken 23551525 times.
✓ Branch 4 taken 341975 times.
✓ Branch 5 taken 5462639 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 341975 times.
30053040 assert(want_privilege == 0 || want_privilege == SELECT_ACL ||
9076 want_privilege == INSERT_ACL || want_privilege == UPDATE_ACL);
9077
3/4
✓ Branch 0 taken 5791055 times.
✓ Branch 1 taken 24261985 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5791055 times.
30053040 assert(!(column_update && (want_privilege & SELECT_ACL)));
9078
2/2
✓ Branch 0 taken 23551409 times.
✓ Branch 1 taken 6501631 times.
30053040 if (want_privilege & SELECT_ACL)
9079 23551409 thd->mark_used_columns = MARK_COLUMNS_READ;
9080
4/4
✓ Branch 0 taken 5804597 times.
✓ Branch 1 taken 697034 times.
✓ Branch 2 taken 13514 times.
✓ Branch 3 taken 5791083 times.
6501631 else if (want_privilege & (INSERT_ACL | UPDATE_ACL) && !column_update)
9081 13514 thd->mark_used_columns = MARK_COLUMNS_WRITE;
9082 else
9083 6488117 thd->mark_used_columns = MARK_COLUMNS_NONE;
9084
9085
5/8
✓ Branch 0 taken 30053199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30053278 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 30053176 times.
✓ Branch 6 taken 102 times.
✗ Branch 7 not taken.
30053040 DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
9086
2/2
✓ Branch 0 taken 10410739 times.
✓ Branch 1 taken 19642539 times.
30053278 if (allow_sum_func)
9087 10410739 thd->lex->allow_sum_func |= (nesting_map)1 << select->nest_level;
9088 30053278 thd->where = THD::DEFAULT_WHERE;
9089 30053278 bool save_is_item_list_lookup = select->is_item_list_lookup;
9090 30053278 select->is_item_list_lookup = false;
9091
9092 /*
9093 To prevent fail on forward lookup we fill it with zerows,
9094 then if we got pointer on zero after find_item_in_list we will know
9095 that it is forward lookup.
9096
9097 There is other way to solve problem: fill array with pointers to list,
9098 but it will be slower.
9099 */
9100
2/2
✓ Branch 0 taken 10410739 times.
✓ Branch 1 taken 19642197 times.
30053278 if (!ref_item_array.is_null()) {
9101
1/2
✓ Branch 0 taken 10410741 times.
✗ Branch 1 not taken.
10410739 size_t num_visible_fields = CountVisibleFields(*fields);
9102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10410736 times.
10410741 assert(ref_item_array.size() >= num_visible_fields);
9103 10410736 memset(ref_item_array.array(), 0, sizeof(Item *) * num_visible_fields);
9104 }
9105
9106 30052933 Ref_item_array ref = ref_item_array;
9107
9108 30052933 mem_root_deque<Item *>::const_iterator typed_it;
9109
2/2
✓ Branch 0 taken 13821260 times.
✓ Branch 1 taken 16231673 times.
30052933 if (typed_items != nullptr) {
9110
1/2
✓ Branch 0 taken 13821053 times.
✗ Branch 1 not taken.
13821260 typed_it = typed_items->begin();
9111 }
9112
6/10
✓ Branch 0 taken 30053009 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 98331719 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 128384583 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 128385250 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 98335171 times.
✓ Branch 9 taken 30050079 times.
128383959 for (auto it = fields->begin(); it != fields->end(); ++it) {
9113 98335171 const size_t old_size = fields->size();
9114
1/2
✓ Branch 0 taken 98335216 times.
✗ Branch 1 not taken.
98335191 Item *item = *it;
9115
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 98335216 times.
98335216 assert(!item->hidden);
9116
1/2
✓ Branch 0 taken 98335310 times.
✗ Branch 1 not taken.
98335216 Item **item_pos = &*it;
9117
7/8
✓ Branch 0 taken 49031338 times.
✓ Branch 1 taken 49303972 times.
✓ Branch 2 taken 49031139 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49027833 times.
✓ Branch 5 taken 3306 times.
✓ Branch 6 taken 3286 times.
✓ Branch 7 taken 98331043 times.
196666333 if ((!item->fixed && item->fix_fields(thd, item_pos)) ||
9118
2/4
✓ Branch 0 taken 98331023 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 98331043 times.
98331805 (item = *item_pos)->check_cols(1)) {
9119
5/8
✓ Branch 0 taken 3286 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3286 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 3285 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
3286 DBUG_PRINT("info",
9120 ("thd->mark_used_columns: %d", thd->mark_used_columns));
9121 3330 return true; /* purecov: inspected */
9122 }
9123
9124 // Check that we don't have a field that is hidden system field. This should
9125 // be caught in Item_field::fix_fields.
9126
5/8
✓ Branch 0 taken 98330621 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34032961 times.
✓ Branch 3 taken 64297660 times.
✓ Branch 4 taken 34033068 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 34033068 times.
98331043 assert(
9127 item->type() != Item::FIELD_ITEM ||
9128 !static_cast<const Item_field *>(item)->field->is_hidden_by_system());
9129
9130
2/2
✓ Branch 0 taken 27318219 times.
✓ Branch 1 taken 71013336 times.
98330728 if (!ref.is_null()) {
9131 27318219 ref[0] = item;
9132 27318219 ref.pop_front();
9133 }
9134 98331549 Item *typed_item = nullptr;
9135
8/10
✓ Branch 0 taken 46291023 times.
✓ Branch 1 taken 52040526 times.
✓ Branch 2 taken 46291325 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 46291522 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 46291507 times.
✓ Branch 7 taken 15 times.
✓ Branch 8 taken 46291585 times.
✓ Branch 9 taken 52040463 times.
98331549 if (typed_items != nullptr && typed_it != typed_items->end()) {
9136
2/4
✓ Branch 0 taken 46290937 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46291488 times.
✗ Branch 3 not taken.
46291585 typed_item = *typed_it++;
9137
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46291488 times.
46291488 assert(!typed_item->hidden);
9138 }
9139
9140
2/2
✓ Branch 0 taken 24816355 times.
✓ Branch 1 taken 73515596 times.
98331951 if (column_update) {
9141
1/2
✓ Branch 0 taken 24816276 times.
✗ Branch 1 not taken.
24816355 Item_field *const field = item->field_for_view_update();
9142
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 24816256 times.
24816276 if (field == nullptr) {
9143
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->item_name.ptr());
9144 44 return true;
9145 }
9146
2/4
✓ Branch 0 taken 24816296 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24816296 times.
24816256 if (item->type() == Item::TRIGGER_FIELD_ITEM) {
9147 char buff[NAME_LEN * 2];
9148 String str(buff, sizeof(buff), &my_charset_bin);
9149 str.length(0);
9150 item->print(thd, &str, QT_ORDINARY);
9151 my_error(ER_INVALID_ASSIGNMENT_TARGET, MYF(0), str.c_ptr());
9152 return true;
9153 }
9154 24816296 TABLE_LIST *tr = field->table_ref;
9155
6/6
✓ Branch 0 taken 363664 times.
✓ Branch 1 taken 24452632 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 363661 times.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 24816293 times.
24816296 if ((want_privilege & UPDATE_ACL) && !tr->is_updatable()) {
9156 /*
9157 The base table of the column may have beeen referenced through a view
9158 or derived table. If so, print the name of the upper-most view
9159 referring to this table in order to print the error message with the
9160 alias of the view as written in the original query instead of the
9161 alias of the base table.
9162 */
9163
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 my_error(ER_NON_UPDATABLE_TABLE, MYF(0), tr->top_table()->alias,
9164 "UPDATE");
9165 11 return true;
9166 }
9167
4/6
✓ Branch 0 taken 24452590 times.
✓ Branch 1 taken 363703 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 24452637 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 24816340 times.
24816293 if ((want_privilege & INSERT_ACL) && !tr->is_insertable()) {
9168 /* purecov: begin inspected */
9169 /*
9170 Generally unused as long as INSERT only can be applied against
9171 one base table, for which the INSERT privileges are checked in
9172 Sql_cmd_insert_base::prepare_inner()
9173 */
9174 my_error(ER_NON_INSERTABLE_TABLE, MYF(0), tr->top_table()->alias,
9175 "INSERT");
9176 return true;
9177 /* purecov: end */
9178 }
9179
2/2
✓ Branch 0 taken 24816306 times.
✓ Branch 1 taken 34 times.
24816340 if (want_privilege & (INSERT_ACL | UPDATE_ACL)) {
9180 24816306 Column_privilege_tracker column_privilege_tr(thd, want_privilege);
9181
3/4
✓ Branch 0 taken 24816577 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 24816565 times.
24816329 if (item->walk(&Item::check_column_privileges, enum_walk::PREFIX,
9182 pointer_cast<uchar *>(thd)))
9183 12 return true;
9184
2/2
✓ Branch 0 taken 24816562 times.
✓ Branch 1 taken 13 times.
24816577 }
9185 24816596 Mark_field mf(MARK_COLUMNS_WRITE);
9186
1/2
✓ Branch 0 taken 24816589 times.
✗ Branch 1 not taken.
24816484 item->walk(&Item::mark_field_in_map, enum_walk::POSTFIX,
9187 pointer_cast<uchar *>(&mf));
9188
2/2
✓ Branch 0 taken 141926 times.
✓ Branch 1 taken 73372913 times.
73515596 } else if (item->data_type() == MYSQL_TYPE_INVALID) {
9189
2/2
✓ Branch 0 taken 141066 times.
✓ Branch 1 taken 860 times.
141926 if (typed_item != nullptr) {
9190
3/6
✓ Branch 0 taken 141066 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141066 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 141066 times.
141066 if (item->propagate_type(thd, Type_properties(*typed_item)))
9191 return true;
9192 } else {
9193
3/6
✓ Branch 0 taken 860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 860 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 860 times.
860 if (item->propagate_type(thd, item->default_data_type())) return true;
9194 }
9195 }
9196
9197
2/2
✓ Branch 0 taken 27318216 times.
✓ Branch 1 taken 71013212 times.
98331428 if (split_sum_funcs) {
9198 /*
9199 (1) Contains a grouped aggregate but is not one. If it is one, we do
9200 not split, but in create_tmp_table() we look at its arguments and add
9201 them to the tmp table, which achieves the same result as for window
9202 functions in (2) but differently.
9203 @todo: unify this (do like (2), probably).
9204 (2) Contains a window function. Even if it is a window function, we
9205 have to collect its arguments and add them to the hidden list of
9206 items, as those arguments have to be stored in the first tmp tables,
9207 and carried forward up to the tmp table where the WF can be
9208 evaluated.
9209 */
9210
3/4
✓ Branch 0 taken 937893 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 694433 times.
✓ Branch 3 taken 243460 times.
28256109 if ((item->has_aggregation() && !(item->type() == Item::SUM_FUNC_ITEM &&
9211
8/8
✓ Branch 0 taken 937893 times.
✓ Branch 1 taken 26380321 times.
✓ Branch 2 taken 694386 times.
✓ Branch 3 taken 47 times.
✓ Branch 4 taken 2971 times.
✓ Branch 5 taken 27071741 times.
✓ Branch 6 taken 246478 times.
✓ Branch 7 taken 27071741 times.
55330819 !item->m_is_window_function)) || //(1)
9212 27074707 item->has_wf()) // (2)
9213
1/2
✓ Branch 0 taken 246478 times.
✗ Branch 1 not taken.
246478 item->split_sum_func(thd, ref_item_array, fields);
9214 }
9215
9216
1/2
✓ Branch 0 taken 98330797 times.
✗ Branch 1 not taken.
98331431 select->select_list_tables |= item->used_tables();
9217
9218
2/2
✓ Branch 0 taken 245470 times.
✓ Branch 1 taken 98085763 times.
98330797 if (old_size != fields->size()) {
9219 // Items have been added (either by fix_fields or by split_sum_func), so
9220 // our iterator is invalidated. Reconstruct it.
9221
3/6
✓ Branch 0 taken 245470 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 245470 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 245470 times.
✗ Branch 5 not taken.
245470 it = std::find(fields->begin(), fields->end(), item);
9222 }
9223 }
9224 30050079 select->is_item_list_lookup = save_is_item_list_lookup;
9225 30050079 thd->lex->allow_sum_func = save_allow_sum_func;
9226 30050079 thd->mark_used_columns = save_mark_used_columns;
9227
5/8
✓ Branch 0 taken 30049774 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30049935 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 101 times.
✓ Branch 5 taken 30049834 times.
✓ Branch 6 taken 101 times.
✗ Branch 7 not taken.
30050079 DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
9228
9229
2/4
✓ Branch 0 taken 30049923 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 30049923 times.
30049935 assert(!thd->is_error());
9230 30049923 return false;
9231 30053253 }
9232
9233 /**
9234 This is an iterator which emits leaf TABLE_LIST nodes in an order suitable
9235 for expansion of 'table_name.*' (qualified asterisk) or '*' (unqualified),
9236 fur use by insert_fields().
9237
9238 First here is some background.
9239
9240 1.
9241 SELECT T1.*, T2.* FROM T1 NATURAL JOIN T2;
9242 has to return all columns of T1 and then all of T2's;
9243 whereas
9244 SELECT * FROM T1 NATURAL JOIN T2;
9245 has to return all columns of T1 and then only those of T2's which are not
9246 common with T1.
9247 Thus, in the first case a NATURAL JOIN isn't considered a leaf (we have to
9248 see through it to find T1.* and T2.*), in the second case it is (we have
9249 to ask it for its column set).
9250 In the first case, the place to search for tables is thus the
9251 TABLE_LIST::next_local list; in the second case it is
9252 TABLE_LIST::next_name_resolution_table.
9253
9254 2.
9255 SELECT * FROM T1 RIGHT JOIN T2 ON < cond >;
9256 is converted, during contextualization, to:
9257 SELECT * FROM T2 LEFT JOIN T1 ON < cond >;
9258 however the former has to return columns of T1 then of T2,
9259 while the latter has to return T2's then T1's.
9260 The conversion has been complete: the lists 'next_local',
9261 'next_name_resolution_table' and Query_block::join_list are as if the user
9262 had typed the second query.
9263
9264 Now to the behaviour of this iterator.
9265
9266 A. If qualified asterisk, the emission order is irrelevant as the caller
9267 tests the table's name; and a NATURAL JOIN isn't a leaf. So, we just follow
9268 the TABLE_LIST::next_local pointers.
9269
9270 B. If non-qualified asterisk, the order must be the left-to-right order
9271 as it was in the query entered by the user. And a NATURAL JOIN is a leaf. So:
9272
9273 B.i. if there was no RIGHT JOIN, then the user-input order is just that of
9274 the 'next_name_resolution' pointers.
9275
9276 B.ii. otherwise, then the order has to be found by a more complex procedure
9277 (function build_vec()):
9278 - first we traverse the join operators, taking into account operators
9279 which had a conversion from RIGHT to LEFT JOIN, we recreate the user-input
9280 order and store leaf TABLE_LISTs in that order in a vector.
9281 - then, in the emission phase, we just emit tables from the vector.
9282
9283 Sequence of calls: constructor, init(), [get_next() N times], destructor.
9284 */
9285 class Tables_in_user_order_iterator {
9286 public:
9287 691589 void init(Query_block *query_block, bool qualified) {
9288
2/4
✓ Branch 0 taken 691589 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 691589 times.
✗ Branch 3 not taken.
691589 assert(query_block && !m_query_block);
9289 691589 m_query_block = query_block;
9290 691589 m_qualified = qualified;
9291 // Vector is needed only if '*' is not qualified and there were RIGHT JOINs
9292
2/2
✓ Branch 0 taken 4119 times.
✓ Branch 1 taken 687470 times.
691589 if (m_qualified) {
9293 4119 m_next = m_query_block->context.table_list;
9294 4119 return;
9295 }
9296
2/2
✓ Branch 0 taken 687204 times.
✓ Branch 1 taken 266 times.
687470 if (!m_query_block->right_joins()) {
9297 687204 m_next = m_query_block->context.first_name_resolution_table;
9298 687204 return;
9299 }
9300 266 m_next = nullptr;
9301 266 m_vec = new std::vector<TABLE_LIST *>;
9302 266 fill_vec(*m_query_block->join_list);
9303 }
9304 691589 ~Tables_in_user_order_iterator() {
9305
2/2
✓ Branch 0 taken 266 times.
✓ Branch 1 taken 691323 times.
691589 delete m_vec;
9306 691589 m_vec = nullptr;
9307 691589 }
9308 1389100 TABLE_LIST *get_next() {
9309
2/2
✓ Branch 0 taken 1388311 times.
✓ Branch 1 taken 789 times.
1389100 if (m_vec == nullptr) {
9310 1388311 auto cur = m_next;
9311
2/2
✓ Branch 0 taken 696996 times.
✓ Branch 1 taken 691315 times.
1388311 if (cur)
9312 696996 m_next =
9313
2/2
✓ Branch 0 taken 5348 times.
✓ Branch 1 taken 691648 times.
696996 m_qualified ? cur->next_local : cur->next_name_resolution_table;
9314 1388311 return cur;
9315 }
9316
2/2
✓ Branch 0 taken 266 times.
✓ Branch 1 taken 523 times.
789 if (m_next_vec_pos == m_vec->size()) return nullptr;
9317 523 return (*m_vec)[m_next_vec_pos++];
9318 }
9319
9320 private:
9321 /// Fills the vector
9322 /// @param tables list of tables and join operators
9323 523 void fill_vec(const mem_root_deque<TABLE_LIST *> &tables) {
9324
5/6
✓ Branch 0 taken 523 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 131 times.
✓ Branch 3 taken 392 times.
✓ Branch 4 taken 131 times.
✓ Branch 5 taken 392 times.
523 if (tables.size() != 0 && tables.front()->join_order_swapped) {
9325
2/4
✓ Branch 0 taken 131 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 131 times.
✗ Branch 3 not taken.
131 assert(tables.size() == 2 && !tables.back()->join_order_swapped);
9326 131 add_table(tables.front());
9327 131 add_table(tables.back());
9328 131 return;
9329 }
9330 // Walk from end to beginning, as join_list is always "reversed"
9331 // (e.g. T1 INNER JOIN T2 leads to join_list = (T2,T1)):
9332
8/14
✓ Branch 0 taken 392 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 518 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 518 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 518 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 910 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 910 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 518 times.
✓ Branch 13 taken 392 times.
910 for (auto it = tables.rbegin(); it != tables.rend(); ++it) add_table(*it);
9333 }
9334 780 void add_table(TABLE_LIST *tr) {
9335
2/2
✓ Branch 0 taken 523 times.
✓ Branch 1 taken 257 times.
780 if (tr->is_leaf_for_name_resolution()) // stop diving here
9336 523 return m_vec->push_back(tr);
9337
1/2
✓ Branch 0 taken 257 times.
✗ Branch 1 not taken.
257 if (tr->nested_join != nullptr) // do dive
9338 257 fill_vec(tr->nested_join->join_list);
9339 }
9340 // Query block which owns the FROM clause to search in
9341 Query_block *m_query_block{nullptr};
9342 /// True/false if we want to expand 'table_name.*' / '*'.
9343 bool m_qualified;
9344 /// If not using the vector: next table to emit
9345 TABLE_LIST *m_next;
9346 /// Vector for the complex case. As the complex case is expected to be rare,
9347 /// we allocate the vector only if needed. nullptr otherwise.
9348 std::vector<TABLE_LIST *> *m_vec{nullptr};
9349 /// If using the vector: position in vector, of next table to emit
9350 uint m_next_vec_pos{0};
9351 };
9352
9353 /*
9354 Drops in all fields instead of current '*' field
9355
9356 SYNOPSIS
9357 insert_fields()
9358 thd Thread handler
9359 query_block Query block
9360 db_name Database name in case of 'database_name.table_name.*'
9361 table_name Table name in case of 'table_name.*'
9362 it Pointer to '*'
9363 any_privileges 0 If we should ensure that we have SELECT privileges
9364 for all columns
9365 1 If any privilege is ok
9366 RETURN
9367 0 ok 'it' is updated to point at last inserted
9368 1 error. Error message is generated but not sent to client
9369 */
9370
9371 691589 bool insert_fields(THD *thd, Query_block *query_block, const char *db_name,
9372 const char *table_name, mem_root_deque<Item *> *fields,
9373 mem_root_deque<Item *>::iterator *it, bool any_privileges) {
9374 char name_buff[NAME_LEN + 1];
9375
1/2
✓ Branch 0 taken 691589 times.
✗ Branch 1 not taken.
691589 DBUG_TRACE;
9376
5/8
✓ Branch 0 taken 691589 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 691589 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 691579 times.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
691589 DBUG_PRINT("arena", ("stmt arena: %p", thd->stmt_arena));
9377
9378 // No need to expand '*' multiple times:
9379
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 691589 times.
691589 assert(query_block->first_execution);
9380
4/4
✓ Branch 0 taken 502 times.
✓ Branch 1 taken 691087 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 691580 times.
692091 if (db_name &&
9381
5/6
✓ Branch 0 taken 497 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 497 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 493 times.
502 (lower_case_table_names || is_infoschema_db(db_name, strlen(db_name)))) {
9382 /*
9383 convert database to lower case for comparison
9384 We can't do this in Item_field as this would change the
9385 'name' of the item which may be used in the select list
9386
9387 We lowercase the 'information_schema' name below to treat it as
9388 case-insensitive even in lower_case_table_names=0.
9389 */
9390
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 strmake(name_buff, db_name, sizeof(name_buff) - 1);
9391
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 my_casedn_str(files_charset_info, name_buff);
9392 9 db_name = name_buff;
9393 }
9394
9395 691589 bool found = false;
9396
9397 TABLE_LIST *tables;
9398
9399 691589 Tables_in_user_order_iterator user_it;
9400
1/2
✓ Branch 0 taken 691589 times.
✗ Branch 1 not taken.
691589 user_it.init(query_block, table_name != nullptr);
9401
9402 while (true) {
9403 1389100 tables = user_it.get_next();
9404
2/2
✓ Branch 0 taken 691581 times.
✓ Branch 1 taken 697519 times.
1389100 if (tables == nullptr) break;
9405
9406
1/2
✓ Branch 0 taken 697519 times.
✗ Branch 1 not taken.
697519 Field_iterator_table_ref field_iterator;
9407 697519 TABLE *const table = tables->table;
9408
9409
2/4
✓ Branch 0 taken 697519 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 697519 times.
697519 assert(tables->is_leaf_for_name_resolution());
9410
9411 704098 if ((table_name &&
9412
9/10
✓ Branch 0 taken 5348 times.
✓ Branch 1 taken 692171 times.
✓ Branch 2 taken 5348 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4117 times.
✓ Branch 5 taken 1231 times.
✓ Branch 6 taken 501 times.
✓ Branch 7 taken 695787 times.
✓ Branch 8 taken 1231 times.
✓ Branch 9 taken 696288 times.
698020 my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
9413
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 501 times.
501 (db_name && strcmp(tables->db, db_name)))
9414 1231 continue;
9415
9416 /*
9417 Ensure that we have access rights to all fields to be inserted. Under
9418 some circumstances, this check may be skipped.
9419
9420 - If any_privileges is true, skip the check.
9421
9422 - If the SELECT privilege has been found as fulfilled already,
9423 the check is skipped.
9424
9425 NOTE: This check is not sufficient: If a user has SELECT_ACL privileges
9426 for a view, it does not mean having the same privileges for the
9427 underlying tables/view. Thus, we have to perform individual column
9428 privilege checks below (or recurse down to all underlying tables here).
9429 */
9430
4/4
✓ Branch 0 taken 693599 times.
✓ Branch 1 taken 2689 times.
✓ Branch 2 taken 707 times.
✓ Branch 3 taken 692892 times.
696288 if (!any_privileges && !(tables->grant.privilege & SELECT_ACL)) {
9431
1/2
✓ Branch 0 taken 707 times.
✗ Branch 1 not taken.
707 field_iterator.set(tables);
9432
3/4
✓ Branch 0 taken 707 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 704 times.
707 if (check_grant_all_columns(thd, SELECT_ACL, &field_iterator))
9433 3 return true;
9434 }
9435
9436 /*
9437 Update the tables used in the query based on the referenced fields. For
9438 views and natural joins this update is performed inside the loop below.
9439 */
9440
2/2
✓ Branch 0 taken 578755 times.
✓ Branch 1 taken 117530 times.
696285 if (table) {
9441 578755 thd->lex->current_query_block()->select_list_tables |= tables->map();
9442 }
9443
9444 /*
9445 Initialize a generic field iterator for the current table reference.
9446 Notice that it is guaranteed that this iterator will iterate over the
9447 fields of a single table reference, because 'tables' is a leaf (for
9448 name resolution purposes).
9449 */
9450
1/2
✓ Branch 0 taken 696285 times.
✗ Branch 1 not taken.
696285 field_iterator.set(tables);
9451
9452
4/6
✓ Branch 0 taken 4816101 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5512386 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4816106 times.
✓ Branch 5 taken 696280 times.
5512386 for (; !field_iterator.end_of_fields(); field_iterator.next()) {
9453
1/2
✓ Branch 0 taken 4816106 times.
✗ Branch 1 not taken.
4816106 Item *const item = field_iterator.create_item(thd);
9454
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4816106 times.
4816111 if (!item) return true; /* purecov: inspected */
9455
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4816106 times.
4816106 assert(item->fixed);
9456
9457
3/4
✓ Branch 0 taken 4816106 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3575034 times.
✓ Branch 3 taken 1241072 times.
4816106 if (item->type() == Item::FIELD_ITEM) {
9458 3575034 Item_field *field = down_cast<Item_field *>(item);
9459 /*
9460 If the column is hidden from users and not used in USING clause of
9461 a join, do not add this column in place of '*'.
9462 */
9463
1/2
✓ Branch 0 taken 3575035 times.
✗ Branch 1 not taken.
3575034 bool is_hidden = field->field->is_hidden();
9464
2/2
✓ Branch 0 taken 737 times.
✓ Branch 1 taken 3574298 times.
3575772 is_hidden &= (tables->join_using_fields == nullptr ||
9465
3/4
✓ Branch 0 taken 737 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 258 times.
✓ Branch 3 taken 479 times.
737 !test_if_string_in_list(field->field_name,
9466 tables->join_using_fields));
9467
2/2
✓ Branch 0 taken 1188 times.
✓ Branch 1 taken 3573847 times.
3575035 if (is_hidden) continue;
9468
9469 /* cache the table for the Item_fields inserted by expanding stars */
9470
2/2
✓ Branch 0 taken 3572706 times.
✓ Branch 1 taken 1141 times.
3573847 if (tables->cacheable_table) field->cached_table = tables;
9471 }
9472
9473
2/2
✓ Branch 0 taken 691581 times.
✓ Branch 1 taken 4123338 times.
4814919 if (!found) {
9474 691581 found = true;
9475
1/2
✓ Branch 0 taken 691581 times.
✗ Branch 1 not taken.
691581 **it = item; /* Replace '*' with the first found item. */
9476 } else {
9477 /* Add 'item' to the SELECT list, after the current one. */
9478
2/4
✓ Branch 0 taken 4123338 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4123337 times.
✗ Branch 3 not taken.
4123338 *it = fields->insert(*it + 1, item);
9479 }
9480
9481 /*
9482 Set privilege information for the fields of newly created views.
9483 We have that (any_priviliges == true) if and only if we are creating
9484 a view. In the time of view creation we can't use the MERGE algorithm,
9485 therefore if 'tables' is itself a view, it is represented by a
9486 temporary table. Thus in this case we can be sure that 'item' is an
9487 Item_field.
9488 */
9489
2/2
✓ Branch 0 taken 44709 times.
✓ Branch 1 taken 4770209 times.
4814918 if (any_privileges) {
9490
4/6
✓ Branch 0 taken 44709 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44678 times.
✓ Branch 3 taken 31 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 31 times.
44709 assert((tables->field_translation == nullptr && table) ||
9491 tables->is_natural_join);
9492
2/4
✓ Branch 0 taken 44709 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 44709 times.
44709 assert(item->type() == Item::FIELD_ITEM);
9493 44709 Item_field *const fld = (Item_field *)item;
9494
1/2
✓ Branch 0 taken 44709 times.
✗ Branch 1 not taken.
44709 const char *field_table_name = field_iterator.get_table_name();
9495
5/6
✓ Branch 0 taken 44637 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 44580 times.
✓ Branch 3 taken 57 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 44709 times.
89289 if (!tables->schema_table && !tables->is_internal() &&
9496 44580 !(fld->have_privileges =
9497
3/6
✓ Branch 0 taken 44580 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44580 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 44580 times.
✗ Branch 5 not taken.
44580 (get_column_grant(thd, field_iterator.grant(),
9498 field_iterator.get_db_name(),
9499
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44580 times.
44580 field_table_name, fld->field_name) &
9500 VIEW_ANY_ACL))) {
9501 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), "ANY",
9502 thd->security_context()->priv_user().str,
9503 thd->security_context()->host_or_ip().str, field_table_name);
9504 return true;
9505 }
9506 }
9507
9508 9629836 thd->lex->current_query_block()->select_list_tables |=
9509
1/2
✓ Branch 0 taken 4814918 times.
✗ Branch 1 not taken.
4814918 item->used_tables();
9510
9511
1/2
✓ Branch 0 taken 4814918 times.
✗ Branch 1 not taken.
4814918 Field *const field = field_iterator.field();
9512
2/2
✓ Branch 0 taken 3573846 times.
✓ Branch 1 taken 1241072 times.
4814918 if (field) {
9513 // Register underlying fields in read map if wanted.
9514
1/2
✓ Branch 0 taken 3573846 times.
✗ Branch 1 not taken.
3573846 field->table->mark_column_used(field, thd->mark_used_columns);
9515 } else {
9516
6/6
✓ Branch 0 taken 1240985 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 1240878 times.
✓ Branch 3 taken 107 times.
✓ Branch 4 taken 1240878 times.
✓ Branch 5 taken 194 times.
1241072 if (thd->want_privilege && tables->is_view_or_derived()) {
9517
3/4
✓ Branch 0 taken 1240878 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 1240873 times.
1240878 if (item->walk(&Item::check_column_privileges, enum_walk::PREFIX,
9518 (uchar *)thd))
9519 5 return true;
9520 }
9521
9522 // Register underlying fields in read map if wanted.
9523 1241067 Mark_field mf(thd->mark_used_columns);
9524
1/2
✓ Branch 0 taken 1241067 times.
✗ Branch 1 not taken.
1241067 item->walk(&Item::mark_field_in_map, enum_walk::SUBQUERY_POSTFIX,
9525 (uchar *)&mf);
9526 }
9527 }
9528
3/3
✓ Branch 0 taken 696280 times.
✓ Branch 1 taken 1231 times.
✓ Branch 2 taken 8 times.
1395030 }
9529
2/2
✓ Branch 0 taken 691576 times.
✓ Branch 1 taken 5 times.
691581 if (found) return false;
9530
9531 /*
9532 TODO: in the case when we skipped all columns because there was a
9533 qualified '*', and all columns were coalesced, we have to give a more
9534 meaningful message than ER_BAD_TABLE_ERROR.
9535 */
9536
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
5 if (!table_name || !*table_name)
9537
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 my_error(ER_NO_TABLES_USED, MYF(0));
9538 else {
9539 2 String tbl_name;
9540
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (db_name) {
9541
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 tbl_name.append(String(db_name, system_charset_info));
9542
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 tbl_name.append('.');
9543 }
9544
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 tbl_name.append(String(table_name, system_charset_info));
9545
9546
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 my_error(ER_BAD_TABLE_ERROR, MYF(0), tbl_name.c_ptr_safe());
9547 2 }
9548
9549 5 return true;
9550 691589 }
9551
9552 /******************************************************************************
9553 ** Fill a record with data (for INSERT or UPDATE)
9554 ** Returns : 1 if some field has wrong type
9555 ******************************************************************************/
9556
9557 /**
9558 Fill fields with given items.
9559
9560 @param thd Thread handler.
9561 @param table Table reference.
9562 @param fields Item_fields list to be filled
9563 @param values Values to fill with.
9564 @param bitmap Bitmap over fields to fill.
9565 @param insert_into_fields_bitmap Bitmap for fields that is set
9566 in fill_record.
9567 @param raise_autoinc_has_expl_non_null_val Set corresponding flag in TABLE
9568 object to true if non-NULL value
9569 is explicitly assigned to
9570 auto-increment field.
9571
9572 @note fill_record() may set TABLE::autoinc_field_has_explicit_non_null_value
9573 to true (even in case of failure!) and its caller should make sure that
9574 it is reset before next call to this function (i.e. before processing
9575 next row) and/or before TABLE instance is returned to table cache.
9576 One can use helper Auto_increment_field_not_null_reset_guard class
9577 to do this.
9578
9579 @note In order to simplify implementation this call is allowed to reset
9580 TABLE::autoinc_field_has_explicit_non_null_value flag even in case
9581 when raise_autoinc_has_expl_non_null_val is false. However, this
9582 should be fine since this flag is supposed to be reset already in
9583 such cases.
9584
9585 @return Operation status
9586 @retval false OK
9587 @retval true Error occurred
9588 */
9589
9590 106738955 bool fill_record(THD *thd, TABLE *table, const mem_root_deque<Item *> &fields,
9591 const mem_root_deque<Item *> &values, MY_BITMAP *bitmap,
9592 MY_BITMAP *insert_into_fields_bitmap,
9593 bool raise_autoinc_has_expl_non_null_val) {
9594
1/2
✓ Branch 0 taken 106825118 times.
✗ Branch 1 not taken.
106738955 DBUG_TRACE;
9595
9596
3/6
✓ Branch 0 taken 106822544 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106864168 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 106864168 times.
106825118 assert(CountVisibleFields(fields) == CountVisibleFields(values));
9597
9598 /*
9599 In case when TABLE object comes to fill_record() from Table Cache it
9600 should have autoinc_field_has_explicit_non_null_value flag set to false.
9601 In case when TABLE object comes to fill_record() after processing
9602 previous row this flag should be reset to false by caller.
9603
9604 Code which implements LOAD DATA is the exception to the above rule
9605 as it calls fill_record() to handle SET clause, after values for
9606 the columns directly coming from loaded from file are set and thus
9607 autoinc_field_has_explicit_non_null_value possibly set to true.
9608 */
9609
4/6
✓ Branch 0 taken 1510032 times.
✓ Branch 1 taken 105354136 times.
✓ Branch 2 taken 1510032 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1510032 times.
✗ Branch 5 not taken.
106864168 assert(table->autoinc_field_has_explicit_non_null_value == false ||
9610 (raise_autoinc_has_expl_non_null_val &&
9611 thd->lex->sql_command == SQLCOM_LOAD));
9612
9613
2/4
✓ Branch 0 taken 106751718 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106786881 times.
✗ Branch 3 not taken.
106864168 auto value_it = VisibleFields(values).begin();
9614
8/14
✓ Branch 0 taken 106782715 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106864813 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 106864476 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 105688737 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 105686252 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 212462826 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 105688126 times.
✓ Branch 13 taken 106774700 times.
212473673 for (Item *fld : VisibleFields(fields)) {
9615
1/2
✓ Branch 0 taken 105687561 times.
✗ Branch 1 not taken.
105688737 Item_field *const field = fld->field_for_view_update();
9616
2/4
✓ Branch 0 taken 105688127 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 105689092 times.
✗ Branch 3 not taken.
105687561 assert(field != nullptr && field->table_ref->table == table);
9617
9618 105689092 Field *const rfield = field->field;
9619
2/4
✓ Branch 0 taken 105690263 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 105690037 times.
✗ Branch 3 not taken.
105689092 Item *value = *value_it++;
9620
9621 /* If bitmap over wanted fields are set, skip non marked fields. */
9622
6/6
✓ Branch 0 taken 1048653 times.
✓ Branch 1 taken 104641384 times.
✓ Branch 2 taken 1017247 times.
✓ Branch 3 taken 30707 times.
✓ Branch 4 taken 1017247 times.
✓ Branch 5 taken 104672091 times.
105690037 if (bitmap && !bitmap_is_set(bitmap, rfield->field_index())) continue;
9623
9624 104672091 bitmap_set_bit(table->fields_set_during_insert, rfield->field_index());
9625
2/2
✓ Branch 0 taken 36457 times.
✓ Branch 1 taken 104634199 times.
104670656 if (insert_into_fields_bitmap)
9626 36457 bitmap_set_bit(insert_into_fields_bitmap, rfield->field_index());
9627
9628 /* Generated columns will be filled after all base columns are done. */
9629
2/2
✓ Branch 0 taken 9005 times.
✓ Branch 1 taken 104661725 times.
104670656 if (rfield->is_gcol()) continue;
9630
9631
2/2
✓ Branch 0 taken 100723514 times.
✓ Branch 1 taken 3938211 times.
104661725 if (raise_autoinc_has_expl_non_null_val &&
9632
2/2
✓ Branch 0 taken 1287020 times.
✓ Branch 1 taken 99436494 times.
100723514 rfield == table->next_number_field)
9633 1287020 table->autoinc_field_has_explicit_non_null_value = true;
9634 /*
9635 We handle errors from save_in_field() by first checking the return
9636 value and then testing thd->is_error(). thd->is_error() can be set
9637 even when save_in_field() does not return a negative value.
9638 @todo save_in_field returns an enum which should never be a negative
9639 value. We should change this test to check for correct enum value.
9640
9641 The below call can reset TABLE::autoinc_field_has_explicit_non_null_value
9642 flag depending on value provided (for details please see
9643 set_field_to_null_with_conversions()). So evaluation of this flag can't
9644 be moved outside of fill_record(), to be done once per statement.
9645 */
9646
2/4
✓ Branch 0 taken 104663815 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 104663815 times.
104661725 if (value->save_in_field(rfield, false) < 0) {
9647 my_error(ER_UNKNOWN_ERROR, MYF(0));
9648 3536 return true;
9649 }
9650
3/4
✓ Branch 0 taken 104664076 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3536 times.
✓ Branch 3 taken 104660540 times.
104663815 if (thd->is_error()) return true;
9651 }
9652
9653
4/4
✓ Branch 0 taken 292844 times.
✓ Branch 1 taken 106483507 times.
✓ Branch 2 taken 78 times.
✓ Branch 3 taken 106776449 times.
107067720 if (table->has_gcol() &&
9654
5/6
✓ Branch 0 taken 292813 times.
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 293020 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 78 times.
✓ Branch 5 taken 292942 times.
292844 update_generated_write_fields(bitmap ? bitmap : table->write_set, table))
9655 78 return true;
9656
9657 /*
9658 TABLE::autoinc_field_has_explicit_non_null_value should not be set to
9659 true in raise_autoinc_has_expl_non_null_val == false mode.
9660 */
9661
3/4
✓ Branch 0 taken 2062353 times.
✓ Branch 1 taken 104714096 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2062353 times.
106776449 assert(table->autoinc_field_has_explicit_non_null_value == false ||
9662 raise_autoinc_has_expl_non_null_val);
9663
9664
1/2
✓ Branch 0 taken 106782371 times.
✗ Branch 1 not taken.
106776449 return thd->is_error();
9665 106785985 }
9666
9667 /**
9668 Check the NOT NULL constraint on all the fields of the current record.
9669
9670 @param thd Thread context.
9671 @param fields Collection of fields.
9672
9673 @return Error status.
9674 */
9675 106717093 static bool check_record(THD *thd, const mem_root_deque<Item *> &fields) {
9676
8/14
✓ Branch 0 taken 106729116 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106799522 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 106799774 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 104593929 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 104594164 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 211368878 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 104593576 times.
✓ Branch 13 taken 106775302 times.
211310601 for (Item *fld : VisibleFields(fields)) {
9677
1/2
✓ Branch 0 taken 104593992 times.
✗ Branch 1 not taken.
104593929 Item_field *field = fld->field_for_view_update();
9678
2/4
✓ Branch 0 taken 104594099 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 104593508 times.
209187607 if (field &&
9679
2/4
✓ Branch 0 taken 104593615 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 104593615 times.
104594099 field->field->check_constraints(ER_BAD_NULL_ERROR) != TYPE_OK) {
9680 my_error(ER_UNKNOWN_ERROR, MYF(0));
9681 return true;
9682 }
9683 }
9684 106775302 return thd->is_error();
9685 }
9686
9687 /**
9688 Check the NOT NULL constraint on all the fields of the current record.
9689
9690 @param thd Thread context.
9691 @param ptr Fields.
9692
9693 @return Error status.
9694 */
9695 183 bool check_record(THD *thd, Field **ptr) {
9696 Field *field;
9697
5/6
✓ Branch 0 taken 514 times.
✓ Branch 1 taken 183 times.
✓ Branch 2 taken 514 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 514 times.
✓ Branch 5 taken 183 times.
697 while ((field = *ptr++) && !thd->is_error()) {
9698
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 514 times.
514 if (field->check_constraints(ER_BAD_NULL_ERROR) != TYPE_OK) return true;
9699 }
9700 183 return thd->is_error();
9701 }
9702
9703 /**
9704 Check the NOT NULL constraint on all the fields explicitly set
9705 in INSERT INTO statement or implicitly set in BEFORE trigger.
9706
9707 @param thd Thread context.
9708 @param ptr Fields.
9709
9710 @return Error status.
9711 */
9712
9713 1938283 static bool check_inserting_record(THD *thd, Field **ptr) {
9714 Field *field;
9715
9716
5/6
✓ Branch 0 taken 11633191 times.
✓ Branch 1 taken 1938244 times.
✓ Branch 2 taken 11633191 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11633191 times.
✓ Branch 5 taken 1938244 times.
13571435 while ((field = *ptr++) && !thd->is_error()) {
9717 11633191 if (bitmap_is_set(field->table->fields_set_during_insert,
9718
4/4
✓ Branch 0 taken 11621769 times.
✓ Branch 1 taken 11422 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 11633152 times.
34888151 field->field_index()) &&
9719
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 11621730 times.
11621769 field->check_constraints(ER_BAD_NULL_ERROR) != TYPE_OK)
9720 39 return true;
9721 }
9722
9723 1938244 return thd->is_error();
9724 }
9725
9726 /**
9727 Invoke check constraints defined on the table.
9728
9729 @param thd Thread handle.
9730 @param table Instance of TABLE.
9731
9732 @retval false If all enforced check constraints are satisfied.
9733 @retval true Otherwise. THD::is_error() may be "true" in this case.
9734 */
9735
9736 112538195 bool invoke_table_check_constraints(THD *thd, const TABLE *table) {
9737
2/2
✓ Branch 0 taken 2026 times.
✓ Branch 1 taken 112536169 times.
112538195 if (table->table_check_constraint_list != nullptr) {
9738
1/2
✓ Branch 0 taken 3473 times.
✗ Branch 1 not taken.
5281 for (auto &table_cc : *table->table_check_constraint_list) {
9739
2/2
✓ Branch 0 taken 2024 times.
✓ Branch 1 taken 1449 times.
3473 if (table_cc.is_enforced()) {
9740 /*
9741 Invoke check constraints only if column(s) used by check constraint is
9742 updated.
9743 */
9744 6009 if ((thd->lex->sql_command == SQLCOM_UPDATE ||
9745
6/6
✓ Branch 0 taken 1959 times.
✓ Branch 1 taken 65 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 1952 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2022 times.
2096 thd->lex->sql_command == SQLCOM_UPDATE_MULTI) &&
9746
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 70 times.
72 !bitmap_is_overlapping(
9747 72 &table_cc.value_generator()->base_columns_map,
9748 72 table->write_set)) {
9749
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 DEBUG_SYNC(thd, "skip_check_constraints_on_unaffected_columns");
9750 2 continue;
9751 }
9752
9753 // Validate check constraint.
9754 2022 Item *check_const_expr_item = table_cc.value_generator()->expr_item;
9755 2022 check_const_expr_item->m_in_check_constraint_exec_ctx = true;
9756
2/2
✓ Branch 0 taken 1449 times.
✓ Branch 1 taken 573 times.
3471 bool is_constraint_violated = (!check_const_expr_item->val_bool() &&
9757
2/2
✓ Branch 0 taken 218 times.
✓ Branch 1 taken 1231 times.
1449 !check_const_expr_item->null_value);
9758 2022 check_const_expr_item->m_in_check_constraint_exec_ctx = false;
9759
9760 /*
9761 If check constraint is violated then report an error. If expression
9762 operand types are incompatible and reported error in conversion even
9763 then report a more user friendly error. Sql_conditions of DA still has
9764 a conversion(actual reported) error in the error stack.
9765 */
9766
5/6
✓ Branch 0 taken 1804 times.
✓ Branch 1 taken 218 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1804 times.
✓ Branch 4 taken 218 times.
✓ Branch 5 taken 1804 times.
2022 if (is_constraint_violated || thd->is_error()) {
9767
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 179 times.
218 if (thd->is_error()) thd->clear_error();
9768 218 my_error(ER_CHECK_CONSTRAINT_VIOLATED, MYF(0), table_cc.name().str);
9769 218 return true;
9770 }
9771 }
9772 }
9773 }
9774
9775 112528135 return false;
9776 }
9777
9778 /**
9779 Check if SQL-statement is INSERT/INSERT SELECT/REPLACE/REPLACE SELECT
9780 and trigger event is ON INSERT. When this condition is true that means
9781 that the statement basically can invoke BEFORE INSERT trigger if it
9782 was created before.
9783
9784 @param event event type for triggers to be invoked
9785 @param sql_command Type of SQL statement
9786
9787 @return Test result
9788 @retval true SQL-statement is
9789 INSERT/INSERT SELECT/REPLACE/REPLACE SELECT
9790 and trigger event is ON INSERT
9791 @retval false Either SQL-statement is not
9792 INSERT/INSERT SELECT/REPLACE/REPLACE SELECT
9793 or trigger event is not ON INSERT
9794 */
9795 34644 static inline bool command_can_invoke_insert_triggers(
9796 enum enum_trigger_event_type event, enum_sql_command sql_command) {
9797 /*
9798 If it's 'INSERT INTO ... ON DUPLICATE KEY UPDATE ...' statement
9799 the event is TRG_EVENT_UPDATE and the SQL-command is SQLCOM_INSERT.
9800 */
9801
4/4
✓ Branch 0 taken 32134 times.
✓ Branch 1 taken 2510 times.
✓ Branch 2 taken 1141 times.
✓ Branch 3 taken 30993 times.
35785 return event == TRG_EVENT_INSERT &&
9802
4/4
✓ Branch 0 taken 339 times.
✓ Branch 1 taken 802 times.
✓ Branch 2 taken 111 times.
✓ Branch 3 taken 228 times.
1141 (sql_command == SQLCOM_INSERT || sql_command == SQLCOM_INSERT_SELECT ||
9803
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 51 times.
111 sql_command == SQLCOM_REPLACE ||
9804 34644 sql_command == SQLCOM_REPLACE_SELECT);
9805 }
9806
9807 /**
9808 Execute BEFORE INSERT trigger.
9809
9810 @param thd thread context
9811 @param table TABLE-object holding list of triggers
9812 to be invoked
9813 @param event event type for triggers to be invoked
9814 @param insert_into_fields_bitmap Bitmap for fields that is set
9815 in fill_record
9816
9817 @return Operation status
9818 @retval false OK
9819 @retval true Error occurred
9820 */
9821 32080 inline bool call_before_insert_triggers(THD *thd, TABLE *table,
9822 enum enum_trigger_event_type event,
9823 MY_BITMAP *insert_into_fields_bitmap) {
9824
2/2
✓ Branch 0 taken 41532 times.
✓ Branch 1 taken 32080 times.
73612 for (Field **f = table->field; *f; ++f) {
9825
4/4
✓ Branch 0 taken 27939 times.
✓ Branch 1 taken 13593 times.
✓ Branch 2 taken 278 times.
✓ Branch 3 taken 41254 times.
69471 if ((*f)->is_flag_set(NO_DEFAULT_VALUE_FLAG) &&
9826
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 27661 times.
27939 !bitmap_is_set(insert_into_fields_bitmap, (*f)->field_index())) {
9827 278 (*f)->set_tmp_null();
9828 }
9829 }
9830
9831 32080 return table->triggers->process_triggers(thd, event, TRG_ACTION_BEFORE, true);
9832 }
9833
9834 /**
9835 Fill fields in list with values from the list of items and invoke
9836 before triggers.
9837
9838 @param thd Thread context.
9839 @param optype_info COPY_INFO structure used for
9840 default values handling.
9841 @param fields Item_fields list to be filled.
9842 @param values Values to fill with.
9843 @param table TABLE-object for the table.
9844 @param event Event type for triggers to be
9845 invoked.
9846 @param num_fields Number of fields in table.
9847 @param raise_autoinc_has_expl_non_null_val Set corresponding flag in
9848 TABLE to true if non-NULL
9849 value is explicitly assigned
9850 to auto-increment field.
9851 @param[out] is_row_changed Set to true if a row is
9852 changed after filling record
9853 and invoking before triggers
9854 for UPDATE operation.
9855 Otherwise set to false.
9856
9857 @note This function assumes that fields which values will be set and
9858 triggers to be invoked belong to the same table, and that
9859 TABLE::record[0] and record[1] buffers correspond to new and old
9860 versions of row respectively.
9861
9862 @note This call may set TABLE::autoinc_field_has_explicit_non_null_value to
9863 true (even in case of failure!) and its caller should make sure that
9864 it is reset appropriately (@sa fill_record()).
9865
9866 @return Operation status
9867 @retval false OK
9868 @retval true Error occurred
9869 */
9870
9871 106711644 bool fill_record_n_invoke_before_triggers(
9872 THD *thd, COPY_INFO *optype_info, const mem_root_deque<Item *> &fields,
9873 const mem_root_deque<Item *> &values, TABLE *table,
9874 enum enum_trigger_event_type event, int num_fields,
9875 bool raise_autoinc_has_expl_non_null_val, bool *is_row_changed) {
9876 // is_row_changed is used by UPDATE operation to set compare_record() result.
9877
3/4
✓ Branch 0 taken 3595864 times.
✓ Branch 1 taken 103115780 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3597252 times.
106711644 assert(is_row_changed == nullptr ||
9878 optype_info->get_operation_type() == COPY_INFO::UPDATE_OPERATION);
9879 /*
9880 Fill DEFAULT functions (like CURRENT_TIMESTAMP) and DEFAULT expressions on
9881 the columns that are not on the list of assigned columns.
9882 */
9883 226331660 auto fill_function_defaults = [table, optype_info, is_row_changed]() {
9884 /*
9885 Unlike INSERT and LOAD, UPDATE operation requires comparison of old
9886 and new records to determine whether function defaults have to be
9887 evaluated.
9888 */
9889
2/2
✓ Branch 0 taken 3595620 times.
✓ Branch 1 taken 103153378 times.
106767983 if (optype_info->get_operation_type() == COPY_INFO::UPDATE_OPERATION) {
9890 3595619 *is_row_changed =
9891
4/4
✓ Branch 0 taken 3455678 times.
✓ Branch 1 taken 139944 times.
✓ Branch 2 taken 3305488 times.
✓ Branch 3 taken 150187 times.
3595620 (!records_are_comparable(table) || compare_records(table));
9892 /*
9893 Evaluate function defaults for columns with ON UPDATE clause only
9894 if any other column of the row is updated.
9895 */
9896
4/4
✓ Branch 0 taken 3445433 times.
✓ Branch 1 taken 150186 times.
✓ Branch 2 taken 43777 times.
✓ Branch 3 taken 3551844 times.
7041054 if (*is_row_changed &&
9897
2/2
✓ Branch 0 taken 43777 times.
✓ Branch 1 taken 3401658 times.
3445433 (optype_info->function_defaults_apply_on_columns(table->write_set))) {
9898
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43777 times.
43777 if (optype_info->set_function_defaults(table)) return true;
9899 }
9900
2/2
✓ Branch 0 taken 2274172 times.
✓ Branch 1 taken 100885717 times.
103153378 } else if (optype_info->function_defaults_apply_on_columns(
9901 table->write_set)) {
9902
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 2279261 times.
2274172 if (optype_info->set_function_defaults(table)) return true;
9903 }
9904 106760599 return false;
9905 106713032 };
9906
9907 /*
9908 If it's 'INSERT INTO ... ON DUPLICATE KEY UPDATE ...' statement
9909 the event is TRG_EVENT_UPDATE and the SQL-command is SQLCOM_INSERT.
9910 */
9911
9912 Trigger_chain *tc =
9913 106713032 table->triggers != nullptr
9914
2/2
✓ Branch 0 taken 42107 times.
✓ Branch 1 taken 106670925 times.
106713032 ? table->triggers->get_triggers(event, TRG_ACTION_BEFORE)
9915 106718344 : nullptr;
9916
9917
2/2
✓ Branch 0 taken 34644 times.
✓ Branch 1 taken 106683700 times.
106718344 if (tc != nullptr) {
9918 bool rc;
9919
9920
1/2
✓ Branch 0 taken 34644 times.
✗ Branch 1 not taken.
34644 table->triggers->enable_fields_temporary_nullability(thd);
9921
2/2
✓ Branch 0 taken 32083 times.
✓ Branch 1 taken 2561 times.
34644 if (command_can_invoke_insert_triggers(event, thd->lex->sql_command)) {
9922
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32083 times.
32083 assert(num_fields);
9923
9924 32083 MY_BITMAP insert_into_fields_bitmap;
9925
1/2
✓ Branch 0 taken 32083 times.
✗ Branch 1 not taken.
32083 bitmap_init(&insert_into_fields_bitmap, nullptr, num_fields);
9926
9927
1/2
✓ Branch 0 taken 32083 times.
✗ Branch 1 not taken.
32083 rc = fill_function_defaults();
9928
9929
1/2
✓ Branch 0 taken 32083 times.
✗ Branch 1 not taken.
32083 if (!rc)
9930
1/2
✓ Branch 0 taken 32083 times.
✗ Branch 1 not taken.
32083 rc = fill_record(thd, table, fields, values, nullptr,
9931 &insert_into_fields_bitmap,
9932 raise_autoinc_has_expl_non_null_val);
9933
9934
2/2
✓ Branch 0 taken 32080 times.
✓ Branch 1 taken 3 times.
32083 if (!rc)
9935
1/2
✓ Branch 0 taken 32080 times.
✗ Branch 1 not taken.
32080 rc = call_before_insert_triggers(thd, table, event,
9936 &insert_into_fields_bitmap);
9937
9938
1/2
✓ Branch 0 taken 32083 times.
✗ Branch 1 not taken.
32083 bitmap_free(&insert_into_fields_bitmap);
9939 } else {
9940
1/2
✓ Branch 0 taken 2561 times.
✗ Branch 1 not taken.
2561 rc = fill_record(thd, table, fields, values, nullptr, nullptr,
9941 raise_autoinc_has_expl_non_null_val);
9942
9943
2/2
✓ Branch 0 taken 2560 times.
✓ Branch 1 taken 1 times.
2561 if (!rc) {
9944
1/2
✓ Branch 0 taken 2560 times.
✗ Branch 1 not taken.
2560 rc = fill_function_defaults();
9945
1/2
✓ Branch 0 taken 2560 times.
✗ Branch 1 not taken.
2560 if (!rc)
9946
1/2
✓ Branch 0 taken 2560 times.
✗ Branch 1 not taken.
2560 rc = table->triggers->process_triggers(thd, event, TRG_ACTION_BEFORE,
9947 true);
9948 // For UPDATE operation, check if row is updated by the triggers.
9949
2/2
✓ Branch 0 taken 2461 times.
✓ Branch 1 taken 49 times.
2510 if (!rc &&
9950
4/4
✓ Branch 0 taken 2510 times.
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 2506 times.
5070 optype_info->get_operation_type() == COPY_INFO::UPDATE_OPERATION &&
9951
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 2407 times.
2461 !(*is_row_changed))
9952 54 *is_row_changed =
9953
5/8
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 54 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 49 times.
54 (!records_are_comparable(table) || compare_records(table));
9954 }
9955 }
9956 /*
9957 Re-calculate generated fields to cater for cases when base columns are
9958 updated by the triggers.
9959 */
9960
2/4
✓ Branch 0 taken 34644 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34644 times.
✗ Branch 3 not taken.
34644 assert(table->pos_in_table_list && !table->pos_in_table_list->is_view());
9961
6/6
✓ Branch 0 taken 34465 times.
✓ Branch 1 taken 179 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 34459 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 34638 times.
34650 if (!rc && table->has_gcol() &&
9962
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 tc->has_updated_trigger_fields(table->write_set)) {
9963 // Dont save old value while re-calculating generated fields.
9964 // Before image will already be saved in the first calculation.
9965
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 table->blobs_need_not_keep_old_value();
9966
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 rc = update_generated_write_fields(table->write_set, table);
9967 }
9968
9969
1/2
✓ Branch 0 taken 34644 times.
✗ Branch 1 not taken.
34644 table->triggers->disable_fields_temporary_nullability();
9970
9971
5/6
✓ Branch 0 taken 34465 times.
✓ Branch 1 taken 179 times.
✓ Branch 2 taken 34465 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
✓ Branch 5 taken 34425 times.
34644 return rc || check_inserting_record(thd, table->field);
9972 } else {
9973
3/4
✓ Branch 0 taken 106741613 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3619 times.
✓ Branch 3 taken 106737994 times.
106683700 if (fill_record(thd, table, fields, values, nullptr, nullptr,
9974 raise_autoinc_has_expl_non_null_val))
9975 3619 return true;
9976
3/4
✓ Branch 0 taken 106726651 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 106726634 times.
106737994 if (fill_function_defaults()) return true;
9977
1/2
✓ Branch 0 taken 106788644 times.
✗ Branch 1 not taken.
106726634 return check_record(thd, fields);
9978 }
9979 }
9980
9981 /**
9982 Fill field buffer with values from Field list.
9983
9984 @param thd Thread handler.
9985 @param table Table reference.
9986 @param ptr Array of fields to fill in.
9987 @param values List of values to fill with.
9988 @param bitmap Bitmap over fields to fill.
9989 @param insert_into_fields_bitmap Bitmap for fields that is set
9990 in fill_record.
9991 @param raise_autoinc_has_expl_non_null_val Set corresponding flag in TABLE
9992 object to true if non-NULL value
9993 is explicitly assigned to
9994 auto-increment field.
9995
9996 @note fill_record() may set TABLE::autoinc_field_has_explicit_non_null_value
9997 to true (even in case of failure!) and its caller should make sure that
9998 it is reset before next call to this function (i.e. before processing
9999 next row) and/or before TABLE instance is returned to table cache.
10000 One can use helper Auto_increment_field_not_null_reset_guard class
10001 to do this.
10002
10003 @note In order to simplify implementation this call is allowed to reset
10004 TABLE::autoinc_field_has_explicit_non_null_value flag even in case
10005 when raise_autoinc_has_expl_non_null_val is false. However, this
10006 should be fine since this flag is supposed to be reset already in
10007 such cases.
10008
10009 @return Operation status
10010 @retval false OK
10011 @retval true Error occurred
10012 */
10013
10014 2376882 bool fill_record(THD *thd, TABLE *table, Field **ptr,
10015 const mem_root_deque<Item *> &values, MY_BITMAP *bitmap,
10016 MY_BITMAP *insert_into_fields_bitmap,
10017 bool raise_autoinc_has_expl_non_null_val) {
10018
1/2
✓ Branch 0 taken 2376882 times.
✗ Branch 1 not taken.
2376882 DBUG_TRACE;
10019
10020 /*
10021 In case when TABLE object comes to fill_record() from Table Cache it
10022 should have autoinc_field_has_explicit_non_null_value flag set to false.
10023 In case when TABLE object comes to fill_record() after processing
10024 previous row this flag should be reset to false by caller.
10025 */
10026
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2376882 times.
2376882 assert(table->autoinc_field_has_explicit_non_null_value == false);
10027
10028 Field *field;
10029
2/4
✓ Branch 0 taken 2376882 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2376882 times.
✗ Branch 3 not taken.
2376882 auto value_it = VisibleFields(values).begin();
10030
6/8
✓ Branch 0 taken 12069208 times.
✓ Branch 1 taken 2376852 times.
✓ Branch 2 taken 12069208 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12069208 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12069208 times.
✓ Branch 7 taken 2376852 times.
14446060 while ((field = *ptr++) && !thd->is_error()) {
10031 // Skip hidden system field.
10032
3/4
✓ Branch 0 taken 12069208 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 12069207 times.
12069208 if (field->is_hidden_by_system()) continue;
10033
10034
2/4
✓ Branch 0 taken 12069207 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12069207 times.
✗ Branch 3 not taken.
12069207 Item *value = *value_it++;
10035
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12069207 times.
12069207 assert(field->table == table);
10036
10037 /* If bitmap over wanted fields are set, skip non marked fields. */
10038
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 12069207 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 12069207 times.
12069207 if (bitmap && !bitmap_is_set(bitmap, field->field_index())) continue;
10039
10040 /*
10041 fill_record could be called as part of multi update and therefore
10042 table->fields_set_during_insert could be NULL.
10043 */
10044
2/2
✓ Branch 0 taken 11579107 times.
✓ Branch 1 taken 490100 times.
12069207 if (table->fields_set_during_insert)
10045 11579107 bitmap_set_bit(table->fields_set_during_insert, field->field_index());
10046
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12069207 times.
12069207 if (insert_into_fields_bitmap)
10047 bitmap_set_bit(insert_into_fields_bitmap, field->field_index());
10048
10049 /* Generated columns will be filled after all base columns are done. */
10050
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12069207 times.
12069207 if (field->is_gcol()) continue;
10051
10052
2/2
✓ Branch 0 taken 11579107 times.
✓ Branch 1 taken 490100 times.
12069207 if (raise_autoinc_has_expl_non_null_val &&
10053
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 11579076 times.
11579107 field == table->next_number_field)
10054 31 table->autoinc_field_has_explicit_non_null_value = true;
10055
10056 /*
10057 @todo We should evaluate what other return values from save_in_field()
10058 that should be treated as errors instead of checking thd->is_error().
10059
10060 The below call can reset TABLE::autoinc_field_has_explicit_non_null_value
10061 flag depending on value provided (for details please see
10062 set_field_to_null_with_conversions()). So evaluation of this flag can't
10063 be moved outside of fill_record(), to be done once per statement.
10064 */
10065
1/2
✓ Branch 0 taken 12069207 times.
✗ Branch 1 not taken.
12069207 if (value->save_in_field(field, false) ==
10066
3/4
✓ Branch 0 taken 12069207 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 12069177 times.
24138414 TYPE_ERR_NULL_CONSTRAINT_VIOLATION ||
10067
3/4
✓ Branch 0 taken 12069207 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 12069177 times.
12069207 thd->is_error())
10068 30 return true;
10069 }
10070
10071
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2376851 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2376852 times.
2376853 if (table->has_gcol() &&
10072
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
1 update_generated_write_fields(bitmap ? bitmap : table->write_set, table))
10073 return true;
10074
10075
6/12
✓ Branch 0 taken 2376852 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2376852 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2376852 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2376852 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2376852 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2376852 times.
2376852 assert(thd->is_error() ||
10076 value_it == VisibleFields(values).end()); // No extra value!
10077
10078 /*
10079 TABLE::autoinc_field_has_explicit_non_null_value should not be set to
10080 true in raise_autoinc_has_expl_non_null_val == false mode.
10081 */
10082
3/4
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 2376821 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 31 times.
2376852 assert(table->autoinc_field_has_explicit_non_null_value == false ||
10083 raise_autoinc_has_expl_non_null_val);
10084
10085
1/2
✓ Branch 0 taken 2376852 times.
✗ Branch 1 not taken.
2376852 return thd->is_error();
10086 2376882 }
10087
10088 /**
10089 Fill fields in array with values from the list of items and invoke
10090 before triggers.
10091
10092 @param thd Thread context.
10093 @param ptr NULL-ended array of fields to be filled.
10094 @param values Values to fill with.
10095 @param table TABLE-object holding list of triggers to be invoked.
10096 @param event Event type for triggers to be invoked.
10097 @param num_fields Number of fields in table.
10098
10099 @note This function assumes that fields which values will be set and triggers
10100 to be invoked belong to the same table, and that TABLE::record[0] and
10101 record[1] buffers correspond to new and old versions of row
10102 respectively.
10103 @note This function is called during handling of statements INSERT/
10104 INSERT SELECT/CREATE SELECT. It means that the only trigger's type
10105 that can be invoked when this function is called is a BEFORE INSERT
10106 trigger so we don't need to make branching based on the result of
10107 execution function command_can_invoke_insert_triggers().
10108
10109 @note Unlike another version of fill_record_n_invoke_before_triggers() this
10110 call tries to set TABLE::autoinc_field_has_explicit_non_null_value to
10111 correct value unconditionally. So this flag can be set to true (even
10112 in case of failure!) and the caller should make sure that it is reset
10113 appropriately (@sa fill_record()).
10114
10115 @retval false OK
10116 @retval true Error occurred.
10117 */
10118
10119 1903834 bool fill_record_n_invoke_before_triggers(THD *thd, Field **ptr,
10120 const mem_root_deque<Item *> &values,
10121 TABLE *table,
10122 enum enum_trigger_event_type event,
10123 int num_fields) {
10124 bool rc;
10125 Trigger_chain *tc =
10126 1903834 table->triggers != nullptr
10127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1903834 times.
1903834 ? table->triggers->get_triggers(event, TRG_ACTION_BEFORE)
10128 1903834 : nullptr;
10129
10130
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1903834 times.
1903834 if (tc != nullptr) {
10131 assert(command_can_invoke_insert_triggers(event, thd->lex->sql_command));
10132 assert(num_fields);
10133
10134 table->triggers->enable_fields_temporary_nullability(thd);
10135
10136 MY_BITMAP insert_into_fields_bitmap;
10137 bitmap_init(&insert_into_fields_bitmap, nullptr, num_fields);
10138
10139 rc = fill_record(thd, table, ptr, values, nullptr,
10140 &insert_into_fields_bitmap, true);
10141 if (!rc)
10142 rc = call_before_insert_triggers(thd, table, event,
10143 &insert_into_fields_bitmap);
10144
10145 /*
10146 Re-calculate generated fields to cater for cases when base columns are
10147 updated by the triggers.
10148 */
10149 if (!rc && *ptr) {
10150 TABLE *table_p = (*ptr)->table;
10151 if (table_p->has_gcol() &&
10152 tc->has_updated_trigger_fields(table_p->write_set)) {
10153 // Dont save old value while re-calculating generated fields.
10154 // Before image will already be saved in the first calculation.
10155 table_p->blobs_need_not_keep_old_value();
10156 rc = update_generated_write_fields(table_p->write_set, table_p);
10157 }
10158 }
10159 bitmap_free(&insert_into_fields_bitmap);
10160 table->triggers->disable_fields_temporary_nullability();
10161 } else
10162 1903834 rc = fill_record(thd, table, ptr, values, nullptr, nullptr, true);
10163
10164
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1903818 times.
1903834 if (rc) return true;
10165
10166 1903818 return check_inserting_record(thd, ptr);
10167 }
10168
10169 /**
10170 Drop all temporary tables which have been left from previous server run.
10171 Used on server start-up.
10172
10173 @return False on success, true on error.
10174 */
10175
10176 11733 bool mysql_rm_tmp_tables(void) {
10177 uint i, idx;
10178 char filePath[FN_REFLEN], *tmpdir;
10179 MY_DIR *dirp;
10180 FILEINFO *file;
10181 THD *thd;
10182 11733 List<LEX_STRING> files;
10183 11733 List_iterator<LEX_STRING> files_it;
10184 LEX_STRING *file_str;
10185 11733 bool result = true;
10186
1/2
✓ Branch 0 taken 11733 times.
✗ Branch 1 not taken.
11733 DBUG_TRACE;
10187
10188
3/6
✓ Branch 0 taken 11733 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11733 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11733 times.
11733 if (!(thd = new THD)) return true; /* purecov: inspected */
10189 11733 thd->thread_stack = (char *)&thd;
10190
1/2
✓ Branch 0 taken 11733 times.
✗ Branch 1 not taken.
11733 thd->store_globals();
10191
10192 11733 MEM_ROOT files_root(PSI_NOT_INSTRUMENTED, 32768);
10193
10194
2/2
✓ Branch 0 taken 11733 times.
✓ Branch 1 taken 11733 times.
23466 for (i = 0; i <= mysql_tmpdir_list.max; i++) {
10195 11733 tmpdir = mysql_tmpdir_list.list[i];
10196 /* See if the directory exists */
10197
2/4
✓ Branch 0 taken 11733 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11733 times.
11733 if (!(dirp = my_dir(tmpdir, MYF(MY_WME | MY_DONT_SORT)))) continue;
10198
10199 /* Find all SQLxxx files in the directory. */
10200
10201
2/2
✓ Branch 0 taken 32829 times.
✓ Branch 1 taken 11733 times.
44562 for (idx = 0; idx < dirp->number_off_files; idx++) {
10202 32829 file = dirp->dir_entry + idx;
10203
10204 /* skipping . and .. */
10205
2/2
✓ Branch 0 taken 25995 times.
✓ Branch 1 taken 6834 times.
32829 if (file->name[0] == '.' &&
10206
5/6
✓ Branch 0 taken 14262 times.
✓ Branch 1 taken 11733 times.
✓ Branch 2 taken 11733 times.
✓ Branch 3 taken 2529 times.
✓ Branch 4 taken 11733 times.
✗ Branch 5 not taken.
25995 (!file->name[1] || (file->name[1] == '.' && !file->name[2])))
10207 23466 continue;
10208
10209
2/2
✓ Branch 0 taken 9352 times.
✓ Branch 1 taken 11 times.
9363 if (strlen(file->name) > tmp_file_prefix_length &&
10210
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 9314 times.
9352 !memcmp(file->name, tmp_file_prefix, tmp_file_prefix_length)) {
10211 38 size_t filePath_len = snprintf(filePath, sizeof(filePath), "%s%c%s",
10212 38 tmpdir, FN_LIBCHAR, file->name);
10213
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 file_str = make_lex_string_root(&files_root, filePath, filePath_len);
10214
10215
3/6
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 38 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 38 times.
38 if (file_str == nullptr || files.push_back(file_str, &files_root)) {
10216 /* purecov: begin inspected */
10217 my_dirend(dirp);
10218 goto err;
10219 /* purecov: end */
10220 }
10221 }
10222 }
10223
1/2
✓ Branch 0 taken 11733 times.
✗ Branch 1 not taken.
11733 my_dirend(dirp);
10224 }
10225
10226 /*
10227 Ask SEs to delete temporary tables.
10228 Pass list of SQLxxx files as a reference.
10229 */
10230
1/2
✓ Branch 0 taken 11733 times.
✗ Branch 1 not taken.
11733 result = ha_rm_tmp_tables(thd, &files);
10231
10232 /* Mimic old behavior, remove suspicious files if SE have not done this. */
10233 11733 files_it.init(files);
10234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11733 times.
11733 while ((file_str = files_it++))
10235 (void)mysql_file_delete(key_file_misc, file_str->str, MYF(0));
10236
10237 11733 err:
10238
1/2
✓ Branch 0 taken 11733 times.
✗ Branch 1 not taken.
11733 files_root.Clear();
10239
1/2
✓ Branch 0 taken 11733 times.
✗ Branch 1 not taken.
11733 delete thd;
10240 11733 return result;
10241 11733 }
10242
10243 /*****************************************************************************
10244 unireg support functions
10245 *****************************************************************************/
10246
10247 /*
10248 free all unused tables
10249
10250 NOTE
10251 This is called by 'handle_manager' when one wants to periodicly flush
10252 all not used tables.
10253 */
10254
10255 2 void tdc_flush_unused_tables() {
10256 2 table_cache_manager.lock_all_and_tdc();
10257 2 table_cache_manager.free_all_unused_tables();
10258 2 table_cache_manager.unlock_all_and_tdc();
10259 2 }
10260
10261 /**
10262 Remove all or some (depending on parameter) instances of TABLE and
10263 TABLE_SHARE from the table definition cache.
10264
10265 @param thd Thread context
10266 @param remove_type Type of removal:
10267 TDC_RT_REMOVE_ALL - remove all TABLE instances and
10268 TABLE_SHARE instance. There
10269 should be no used TABLE objects
10270 and caller should have exclusive
10271 metadata lock on the table.
10272 TDC_RT_REMOVE_NOT_OWN - remove all TABLE instances
10273 except those that belong to
10274 this thread. There should be
10275 no TABLE objects used by other
10276 threads and caller should have
10277 exclusive metadata lock on the
10278 table.
10279 TDC_RT_REMOVE_UNUSED - remove all unused TABLE
10280 instances (if there are no
10281 used instances will also
10282 remove TABLE_SHARE).
10283 TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE -
10284 remove all TABLE instances
10285 except those that belong to
10286 this thread, but don't mark
10287 TABLE_SHARE as old. There
10288 should be no TABLE objects
10289 used by other threads and
10290 caller should have exclusive
10291 metadata lock on the table.
10292 TDC_RT_MARK_FOR_REOPEN - remove all unused TABLE
10293 instances, mark used TABLE
10294 instances as needing reopen.
10295 @param db Name of database
10296 @param table_name Name of table
10297 @param has_lock If true, LOCK_open is already acquired
10298
10299 @note It assumes that table instances are already not used by any
10300 (other) thread (this should be achieved by using meta-data locks).
10301 */
10302
10303 1972266 void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
10304 const char *db, const char *table_name, bool has_lock) {
10305 char key[MAX_DBKEY_LENGTH];
10306 size_t key_length;
10307
10308
2/2
✓ Branch 0 taken 1971958 times.
✓ Branch 1 taken 308 times.
1972266 if (!has_lock)
10309
1/2
✓ Branch 0 taken 1971958 times.
✗ Branch 1 not taken.
1971958 table_cache_manager.lock_all_and_tdc();
10310 else
10311
1/2
✓ Branch 0 taken 309 times.
✗ Branch 1 not taken.
309 table_cache_manager.assert_owner_all_and_tdc();
10312
10313
6/8
✓ Branch 0 taken 1971577 times.
✓ Branch 1 taken 690 times.
✓ Branch 2 taken 1970973 times.
✓ Branch 3 taken 604 times.
✓ Branch 4 taken 1970973 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1970973 times.
1972267 assert(remove_type == TDC_RT_REMOVE_UNUSED ||
10314 remove_type == TDC_RT_MARK_FOR_REOPEN ||
10315 thd->mdl_context.owns_equal_or_stronger_lock(
10316 MDL_key::TABLE, db, table_name, MDL_EXCLUSIVE));
10317
10318
1/2
✓ Branch 0 taken 1972267 times.
✗ Branch 1 not taken.
1972267 key_length = create_table_def_key(db, table_name, key);
10319
10320
2/4
✓ Branch 0 taken 1972267 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1972267 times.
✗ Branch 3 not taken.
1972267 auto it = table_def_cache->find(string(key, key_length));
10321
10322 // If the table has a shadow copy in a secondary storage engine, or
10323 // if we don't know if the table has a shadow copy, we must also
10324 // attempt to evict the secondary table from the cache.
10325 const bool remove_secondary =
10326
4/4
✓ Branch 0 taken 409703 times.
✓ Branch 1 taken 1562564 times.
✓ Branch 2 taken 256 times.
✓ Branch 3 taken 409447 times.
1972267 it == table_def_cache->end() || it->second->has_secondary_engine();
10327
10328 // Helper function that evicts the TABLE_SHARE pointed to by an iterator.
10329 3535087 auto remove_table = [&](Table_definition_cache::iterator my_it) {
10330
2/2
✓ Branch 0 taken 3125275 times.
✓ Branch 1 taken 409812 times.
3535087 if (my_it == table_def_cache->end()) return;
10331 409812 TABLE_SHARE *share = my_it->second.get();
10332 /*
10333 Since share->ref_count is incremented when a table share is opened
10334 in get_table_share(), before LOCK_open is temporarily released, it
10335 is sufficient to check this condition alone and ignore the
10336 share->m_open_in_progress flag.
10337
10338 Note that it is safe to call table_cache_manager.free_table() for
10339 shares with m_open_in_progress == true, since such shares don't
10340 have any TABLE objects associated.
10341 */
10342
2/2
✓ Branch 0 taken 306735 times.
✓ Branch 1 taken 103077 times.
409812 if (share->ref_count() > 0) {
10343 /*
10344 Set share's version to zero in order to ensure that it gets
10345 automatically deleted once it is no longer referenced.
10346
10347 Note that code in TABLE_SHARE::wait_for_old_version() assumes
10348 that marking share as old and removal of its unused tables
10349 and of the share itself from TDC happens atomically under
10350 protection of LOCK_open, or, putting it another way, that
10351 TDC does not contain old shares which don't have any tables
10352 used.
10353 */
10354
2/2
✓ Branch 0 taken 259767 times.
✓ Branch 1 taken 46968 times.
306735 if (remove_type != TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE &&
10355
2/2
✓ Branch 0 taken 259163 times.
✓ Branch 1 taken 604 times.
259767 remove_type != TDC_RT_MARK_FOR_REOPEN)
10356 259163 share->clear_version();
10357 306735 table_cache_manager.free_table(thd, remove_type, share);
10358
1/2
✓ Branch 0 taken 103077 times.
✗ Branch 1 not taken.
103077 } else if (remove_type != TDC_RT_MARK_FOR_REOPEN) {
10359 // There are no TABLE objects associated, so just remove the
10360 // share immediately. (Assert: When called with
10361 // TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE, there should always be a
10362 // TABLE object associated with the primary TABLE_SHARE.)
10363
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 103071 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
103077 assert(remove_type != TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE ||
10364 share->is_secondary_engine());
10365
1/2
✓ Branch 0 taken 103077 times.
✗ Branch 1 not taken.
103077 table_def_cache->erase(to_string(share->table_cache_key));
10366 }
10367 1972267 };
10368
10369
1/2
✓ Branch 0 taken 1972267 times.
✗ Branch 1 not taken.
1972267 remove_table(it);
10370
10371
2/2
✓ Branch 0 taken 1562820 times.
✓ Branch 1 taken 409447 times.
1972267 if (remove_secondary)
10372
2/4
✓ Branch 0 taken 1562820 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1562820 times.
✗ Branch 3 not taken.
1562820 remove_table(
10373
1/2
✓ Branch 0 taken 1562820 times.
✗ Branch 1 not taken.
3125640 table_def_cache->find(create_table_def_key_secondary(db, table_name)));
10374
10375
3/4
✓ Branch 0 taken 1971958 times.
✓ Branch 1 taken 309 times.
✓ Branch 2 taken 1971958 times.
✗ Branch 3 not taken.
1972267 if (!has_lock) table_cache_manager.unlock_all_and_tdc();
10376 1972267 }
10377
10378 2576 int setup_ftfuncs(const THD *thd, Query_block *query_block) {
10379
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2576 times.
2576 assert(query_block->has_ft_funcs());
10380
10381
1/2
✓ Branch 0 taken 2576 times.
✗ Branch 1 not taken.
2576 List_iterator<Item_func_match> li(*(query_block->ftfunc_list)),
10382
1/2
✓ Branch 0 taken 2576 times.
✗ Branch 1 not taken.
2576 lj(*(query_block->ftfunc_list));
10383 Item_func_match *ftf, *ftf2;
10384
10385
2/2
✓ Branch 0 taken 2739 times.
✓ Branch 1 taken 2546 times.
5285 while ((ftf = li++)) {
10386
6/8
✓ Branch 0 taken 2739 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2739 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 30 times.
✓ Branch 5 taken 2709 times.
✓ Branch 6 taken 30 times.
✓ Branch 7 taken 2709 times.
2739 if (ftf->table_ref && ftf->fix_index(thd)) return 1;
10387 2709 lj.rewind();
10388
10389 /*
10390 Notice that expressions added late (e.g. in ORDER BY) may be deleted
10391 during resolving. It is therefore important that an "early" expression
10392 is used as master for a "late" one, and not the other way around.
10393 */
10394
2/2
✓ Branch 0 taken 202 times.
✓ Branch 1 taken 2709 times.
2911 while ((ftf2 = lj++) != ftf) {
10395
7/8
✓ Branch 0 taken 202 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 113 times.
✓ Branch 3 taken 89 times.
✓ Branch 4 taken 103 times.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 103 times.
✓ Branch 7 taken 99 times.
202 if (ftf->eq(ftf2, true) && !ftf->master) ftf2->set_master(ftf);
10396 }
10397 }
10398
10399 2546 return 0;
10400 }
10401
10402 2397 bool init_ftfuncs(THD *thd, Query_block *query_block) {
10403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2397 times.
2397 assert(query_block->has_ft_funcs());
10404
10405
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2397 times.
2397 DBUG_PRINT("info", ("Performing FULLTEXT search"));
10406 2397 THD_STAGE_INFO(thd, stage_fulltext_initialization);
10407
10408
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2383 times.
2397 if (thd->lex->using_hypergraph_optimizer) {
10409 // Set the no_ranking hint if ranking of the results is not required. The
10410 // old optimizer does this when it determines which scan to use. The
10411 // hypergraph optimizer doesn't know until the full plan is built, so do it
10412 // here, just before the full-text search is performed.
10413
5/8
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 34 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20 times.
✓ Branch 7 taken 14 times.
34 for (Item_func_match &ifm : *query_block->ftfunc_list) {
10414
4/6
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 20 times.
20 if (ifm.master == nullptr && ifm.can_skip_ranking()) {
10415 ifm.get_hints()->set_hint_flag(FT_NO_RANKING);
10416 }
10417 }
10418 }
10419
10420
5/8
✓ Branch 0 taken 2397 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2397 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4930 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2539 times.
✓ Branch 7 taken 2391 times.
4930 for (Item_func_match &ifm : *query_block->ftfunc_list) {
10421
3/4
✓ Branch 0 taken 2539 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 2533 times.
2539 if (ifm.init_search(thd)) {
10422 6 return true;
10423 }
10424 }
10425
10426 2391 return false;
10427 }
10428
10429 2 bool is_equal(const LEX_CSTRING *a, const LEX_CSTRING *b) noexcept {
10430
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 return a->length == b->length && !strncmp(a->str, b->str, a->length);
10431 }
10432
10433 612 static bool is_cond_equal(const Item *cond) noexcept {
10434
1/2
✓ Branch 0 taken 612 times.
✗ Branch 1 not taken.
1224 return (cond->type() == Item::FUNC_ITEM &&
10435
2/2
✓ Branch 0 taken 498 times.
✓ Branch 1 taken 114 times.
612 (((const Item_func *)cond)->functype() == Item_func::EQ_FUNC ||
10436
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 498 times.
1110 ((const Item_func *)cond)->functype() == Item_func::EQUAL_FUNC));
10437 }
10438
10439 498 static bool is_cond_mult_equal(const Item *cond) noexcept {
10440
1/2
✓ Branch 0 taken 498 times.
✗ Branch 1 not taken.
996 return (cond->type() == Item::FUNC_ITEM &&
10441
2/2
✓ Branch 0 taken 463 times.
✓ Branch 1 taken 35 times.
996 (((const Item_func *)cond)->functype() == Item_func::MULT_EQUAL_FUNC));
10442 }
10443
10444 /*
10445 And-or graph truth propagation algorithm is used to calculate if the
10446 statement is ordered or not.
10447
10448 Nodes:
10449 Join_node - And node, this is the root, successors are a list of
10450 Const_ordered_table_node.
10451 Const_ordered_table_node - Or node, have two Table_node as successors,
10452 one for ordered table, and the other for constant table.
10453 Table_node - Or node, have a list of Key_node and one All_columns_node
10454 as successors.
10455 Key_node - And node, successors are a list of Column_node that corresponding
10456 to the fields of the key.
10457 All_columns_node - And node, successors are a list of Column_node of all
10458 fields of the table.
10459 Column_node - Or node, represent a field of the table, it will take a
10460 Table_node as a successor, which means if a table is true
10461 (const or ordered), the all its columns are const or ordered.
10462 Successors to other column nodes will be added mutually if
10463 there is an equation to that field in the condition. The
10464 column nodes for fields that are in the ORDER BY or are
10465 equal to constants are added to the init_nodes of the Join_node,
10466 which is used as the initial true values of the propagation.
10467 */
10468
10469 /*
10470 Abstract base class for and-or node.
10471 */
10472 class Node {
10473 public:
10474 22810 Node() noexcept : todo(0) {}
10475 1622 virtual ~Node() {}
10476 virtual void add_successor(Node *node) = 0;
10477 /* Number of successors need to be true to make this node true. */
10478 uint todo;
10479 /* List of nodes that this node is a successor */
10480 List<Node> predecessors;
10481 };
10482
10483 /*
10484 Or node will be true if any of its successors is true.
10485 */
10486 class Or_node : public Node {
10487 public:
10488 14121 Or_node() noexcept : Node() {}
10489 22436 void add_successor(Node *node) override {
10490 22436 todo = 1;
10491 22436 node->predecessors.push_back(this);
10492 22436 }
10493 };
10494
10495 /*
10496 And node can only be true if all its successors are true.
10497 */
10498 class And_node : public Node {
10499 public:
10500 8689 And_node() noexcept : Node() {}
10501 11497 void add_successor(Node *node) override {
10502 11497 todo++;
10503 11497 node->predecessors.push_back(this);
10504 11497 }
10505 };
10506
10507 typedef Or_node Column_node;
10508 typedef And_node Key_node;
10509 typedef And_node All_columns_node;
10510
10511 class Table_node final : public Or_node {
10512 public:
10513 Table_node(const TABLE *table_arg);
10514 Column_node *get_column_node(const Field *field) const noexcept;
10515 Column_node *create_column_node(const Field *field);
10516 All_columns_node *create_all_columns_node();
10517 Key_node *create_key_node(const KEY *key_info);
10518
10519 private:
10520 const TABLE *table;
10521 Column_node **columns;
10522 };
10523
10524 2190 Table_node::Table_node(const TABLE *table_arg)
10525 2190 : table(table_arg),
10526 6570 columns((Column_node **)(*THR_MALLOC)
10527
2/4
✓ Branch 0 taken 2190 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2190 times.
✗ Branch 3 not taken.
2190 ->Alloc(sizeof(Column_node *) * table->s->fields)) {
10528 2190 memset(columns, 0, sizeof(Column_node *) * table->s->fields);
10529
10530
2/2
✓ Branch 0 taken 606 times.
✓ Branch 1 taken 1584 times.
2190 if (table->s->primary_key == MAX_KEY) {
10531
2/4
✓ Branch 0 taken 606 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 606 times.
✗ Branch 3 not taken.
606 add_successor(create_all_columns_node());
10532 606 return;
10533 }
10534 uint key;
10535
2/2
✓ Branch 0 taken 8830 times.
✓ Branch 1 taken 1584 times.
10414 for (key = 0; key < table->s->keys; key++) {
10536
2/2
✓ Branch 0 taken 7272 times.
✓ Branch 1 taken 1558 times.
8830 if ((table->s->key_info[key].flags & (HA_NOSAME | HA_NULL_PART_KEY)) ==
10537 HA_NOSAME)
10538
2/4
✓ Branch 0 taken 7272 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7272 times.
✗ Branch 3 not taken.
7272 add_successor(create_key_node(&table->s->key_info[key]));
10539 }
10540 }
10541
10542 25754 inline Column_node *Table_node::get_column_node(const Field *field) const
10543 noexcept {
10544 25754 return columns[field->field_index()];
10545 }
10546
10547 12877 inline Column_node *Table_node::create_column_node(const Field *field) {
10548
2/2
✓ Branch 0 taken 10836 times.
✓ Branch 1 taken 2041 times.
12877 if (!get_column_node(field)) {
10549
1/2
✓ Branch 0 taken 10836 times.
✗ Branch 1 not taken.
10836 Column_node *column = new (*THR_MALLOC) Column_node;
10550 10836 columns[field->field_index()] = column;
10551 /*
10552 If the table is ORDERED or CONST, then all the columns are
10553 ORDERED or CONST, so add the table as an successor of the column
10554 node (Or_node).
10555 */
10556 10836 column->add_successor(this);
10557 }
10558 12877 return get_column_node(field);
10559 }
10560
10561 606 All_columns_node *Table_node::create_all_columns_node() {
10562
1/2
✓ Branch 0 taken 606 times.
✗ Branch 1 not taken.
606 All_columns_node *node = new (*THR_MALLOC) All_columns_node;
10563 606 uint i = 0;
10564
2/2
✓ Branch 0 taken 1532 times.
✓ Branch 1 taken 606 times.
2138 for (i = 0; i < table->s->fields; i++) {
10565 1532 Column_node *column = create_column_node(table->field[i]);
10566 1532 node->add_successor(column);
10567 }
10568 606 return node;
10569 }
10570
10571 7272 Key_node *Table_node::create_key_node(const KEY *key_info) {
10572
1/2
✓ Branch 0 taken 7272 times.
✗ Branch 1 not taken.
7272 Key_node *node = new (*THR_MALLOC) Key_node;
10573 7272 uint key_parts = key_info->user_defined_key_parts;
10574 uint i;
10575
2/2
✓ Branch 0 taken 8870 times.
✓ Branch 1 taken 7272 times.
16142 for (i = 0; i < key_parts; i++) {
10576 8870 KEY_PART_INFO *key_part = &key_info->key_part[i];
10577 8870 Field *field = table->field[key_part->fieldnr - 1];
10578 8870 node->add_successor(create_column_node(field));
10579 }
10580 7272 return node;
10581 }
10582
10583 class Const_ordered_table_node final : public Or_node {
10584 public:
10585 Const_ordered_table_node(const TABLE *table_arg);
10586 4651 const TABLE *get_table() const noexcept { return table; }
10587 Column_node *get_ordered_column_node(const Field *field) const;
10588 Column_node *get_const_column_node(const Field *field) const;
10589
10590 private:
10591 const TABLE *table;
10592 Table_node *ordered_table_node;
10593 Table_node *const_table_node;
10594 };
10595
10596 1095 Const_ordered_table_node::Const_ordered_table_node(const TABLE *table_arg)
10597 1095 : table(table_arg),
10598
2/4
✓ Branch 0 taken 1095 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1095 times.
✗ Branch 3 not taken.
1095 ordered_table_node(new (*THR_MALLOC) Table_node(table)),
10599
4/8
✓ Branch 0 taken 1095 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1095 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1095 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1095 times.
✗ Branch 7 not taken.
2190 const_table_node(new (*THR_MALLOC) Table_node(table)) {
10600
1/2
✓ Branch 0 taken 1095 times.
✗ Branch 1 not taken.
1095 add_successor(ordered_table_node);
10601
1/2
✓ Branch 0 taken 1095 times.
✗ Branch 1 not taken.
1095 add_successor(const_table_node);
10602 1095 }
10603
10604 1482 inline Column_node *Const_ordered_table_node::get_ordered_column_node(
10605 const Field *field) const {
10606 1482 return ordered_table_node->create_column_node(field);
10607 }
10608
10609 993 inline Column_node *Const_ordered_table_node::get_const_column_node(
10610 const Field *field) const {
10611 993 return const_table_node->create_column_node(field);
10612 }
10613
10614 class Join_node : public And_node {
10615 public:
10616 Join_node(const mem_root_deque<TABLE_LIST *> *join_list, Item *cond,
10617 const ORDER *order);
10618 Join_node(const TABLE_LIST *table, Item *cond, const ORDER *order);
10619 bool is_ordered() const;
10620
10621 private:
10622 void add_join_list(const mem_root_deque<TABLE_LIST *> *join_list);
10623 Const_ordered_table_node *add_table(const TABLE *table);
10624 Const_ordered_table_node *get_const_ordered_table_node(const TABLE *table);
10625 Column_node *get_ordered_column_node(const Field *field);
10626 Column_node *get_const_column_node(const Field *field);
10627 void add_ordered_columns(const ORDER *order);
10628 void add_const_equi_columns(Item *cond);
10629 void add_const_column(const Field *field);
10630 void add_equi_column(const Field *left, const Field *right);
10631 bool field_belongs_to_tables(const Field *field) noexcept;
10632 List<Const_ordered_table_node> tables;
10633 List<Node> init_nodes;
10634 ulong max_sort_length;
10635 };
10636
10637 693 inline void Join_node::add_join_list(
10638 const mem_root_deque<TABLE_LIST *> *join_list) {
10639 693 Item *join_cond = join_list->front()->join_cond();
10640
7/12
✓ Branch 0 taken 693 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 693 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 977 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 977 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1670 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 977 times.
✓ Branch 11 taken 693 times.
1670 for (auto table : *join_list)
10641
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 966 times.
977 if (table->nested_join)
10642
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 add_join_list(&table->nested_join->join_list);
10643 else
10644
1/2
✓ Branch 0 taken 966 times.
✗ Branch 1 not taken.
966 add_table(table->table);
10645 693 add_const_equi_columns(join_cond);
10646 693 }
10647
10648 1095 inline Const_ordered_table_node *Join_node::add_table(const TABLE *table) {
10649 Const_ordered_table_node *tableNode =
10650
2/4
✓ Branch 0 taken 1095 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1095 times.
✗ Branch 3 not taken.
1095 new (*THR_MALLOC) Const_ordered_table_node(table);
10651 1095 add_successor(tableNode);
10652 1095 tables.push_back(tableNode);
10653 1095 return tableNode;
10654 }
10655
10656 681 inline Join_node::Join_node(const mem_root_deque<TABLE_LIST *> *join_list,
10657 681 Item *cond, const ORDER *order) {
10658
2/4
✓ Branch 0 taken 681 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 681 times.
681 assert(!join_list->empty());
10659
1/2
✓ Branch 0 taken 681 times.
✗ Branch 1 not taken.
681 max_sort_length = current_thd->variables.max_sort_length;
10660
1/2
✓ Branch 0 taken 681 times.
✗ Branch 1 not taken.
681 add_join_list(join_list);
10661
1/2
✓ Branch 0 taken 681 times.
✗ Branch 1 not taken.
681 add_ordered_columns(order);
10662
1/2
✓ Branch 0 taken 681 times.
✗ Branch 1 not taken.
681 add_const_equi_columns(cond);
10663 681 }
10664
10665 130 inline Join_node::Join_node(const TABLE_LIST *table, Item *cond,
10666 130 const ORDER *order) {
10667
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 max_sort_length = current_thd->variables.max_sort_length;
10668
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 1 times.
130 if (table->table) {
10669
1/2
✓ Branch 0 taken 129 times.
✗ Branch 1 not taken.
129 add_table(table->table);
10670 } else {
10671
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 add_join_list(table->view_tables);
10672 }
10673
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 add_ordered_columns(order);
10674
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 add_const_equi_columns(cond);
10675 130 }
10676
10677 2475 inline Const_ordered_table_node *Join_node::get_const_ordered_table_node(
10678 const TABLE *table) {
10679
1/2
✓ Branch 0 taken 2475 times.
✗ Branch 1 not taken.
2475 List_iterator<Const_ordered_table_node> it(tables);
10680 Const_ordered_table_node *node;
10681
1/2
✓ Branch 0 taken 4493 times.
✗ Branch 1 not taken.
4493 while ((node = it++)) {
10682
2/2
✓ Branch 0 taken 2475 times.
✓ Branch 1 taken 2018 times.
4493 if (node->get_table() == table) return node;
10683 }
10684 assert(0);
10685 return add_table(table);
10686 }
10687
10688 136 inline bool Join_node::field_belongs_to_tables(const Field *field) noexcept {
10689 136 List_iterator<Const_ordered_table_node> it(tables);
10690 Const_ordered_table_node *node;
10691
1/2
✓ Branch 0 taken 158 times.
✗ Branch 1 not taken.
158 while ((node = it++)) {
10692
2/2
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 22 times.
158 if (node->get_table() == field->table) return true;
10693 }
10694 return false;
10695 }
10696
10697 1482 inline Column_node *Join_node::get_ordered_column_node(const Field *field) {
10698 1482 return get_const_ordered_table_node(field->table)
10699 1482 ->get_ordered_column_node(field);
10700 }
10701
10702 993 inline Column_node *Join_node::get_const_column_node(const Field *field) {
10703 993 return get_const_ordered_table_node(field->table)
10704 993 ->get_const_column_node(field);
10705 }
10706
10707 227 inline void Join_node::add_const_column(const Field *field) {
10708 227 Column_node *column = get_const_column_node(field);
10709 227 init_nodes.push_back(column);
10710 227 }
10711
10712 383 void Join_node::add_equi_column(const Field *left, const Field *right) {
10713 383 Column_node *left_column = get_const_column_node(left);
10714 383 Column_node *right_column = get_const_column_node(right);
10715 383 left_column->add_successor(right_column);
10716 383 right_column->add_successor(left_column);
10717
10718 383 left_column = get_ordered_column_node(left);
10719 383 right_column = get_ordered_column_node(right);
10720 383 left_column->add_successor(right_column);
10721 383 right_column->add_successor(left_column);
10722 383 }
10723
10724 687 inline bool is_cond_or(const Item *item) noexcept {
10725
2/2
✓ Branch 0 taken 612 times.
✓ Branch 1 taken 75 times.
687 if (item->type() != Item::COND_ITEM) return false;
10726
10727 75 const Item_cond *cond_item = (const Item_cond *)item;
10728 75 return (cond_item->functype() == Item_func::COND_OR_FUNC);
10729 }
10730
10731 687 static bool is_cond_and(const Item *item) noexcept {
10732
2/2
✓ Branch 0 taken 612 times.
✓ Branch 1 taken 75 times.
687 if (item->type() != Item::COND_ITEM) return false;
10733
10734 75 const Item_cond *cond_item = (const Item_cond *)item;
10735 75 return (cond_item->functype() == Item_func::COND_AND_FUNC);
10736 }
10737
10738 1803 void Join_node::add_const_equi_columns(Item *cond) {
10739
2/2
✓ Branch 0 taken 1116 times.
✓ Branch 1 taken 687 times.
1803 if (!cond) return;
10740
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 687 times.
687 if (is_cond_or(cond)) return;
10741
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 612 times.
687 if (is_cond_and(cond)) {
10742 75 const List<Item> *args = ((const Item_cond *)cond)->argument_list();
10743
1/2
✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
75 List_iterator<Item> it(*const_cast<List<Item>*>(args));
10744 Item *c;
10745
3/4
✓ Branch 0 taken 299 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 299 times.
✓ Branch 3 taken 75 times.
374 while ((c = it++)) add_const_equi_columns(c);
10746 75 return;
10747 }
10748
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 498 times.
612 if (is_cond_equal(cond)) {
10749 uint i;
10750 114 Field *first_field = nullptr;
10751 114 Field *second_field = nullptr;
10752 114 Item **args = ((const Item_func *)cond)->arguments();
10753 114 uint arg_count = ((const Item_func *)cond)->argument_count();
10754 114 bool const_value = false;
10755
10756
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 114 times.
114 assert(arg_count == 2);
10757
10758 114 bool variable_field = false;
10759
2/2
✓ Branch 0 taken 228 times.
✓ Branch 1 taken 114 times.
342 for (i = 0; i < arg_count; i++) {
10760
5/6
✓ Branch 0 taken 136 times.
✓ Branch 1 taken 92 times.
✓ Branch 2 taken 136 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 136 times.
✓ Branch 5 taken 92 times.
364 if (args[i]->real_item()->type() == Item::FIELD_ITEM &&
10761 136 (variable_field = field_belongs_to_tables(
10762 136 ((Item_field *)args[i]->real_item())->field))) {
10763
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 22 times.
136 if (!first_field)
10764 114 first_field = ((const Item_field *)args[i]->real_item())->field;
10765 else
10766 22 second_field = ((const Item_field *)args[i]->real_item())->field;
10767
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 92 times.
✗ Branch 5 not taken.
92 } else if (args[i]->real_item()->basic_const_item() || !variable_field) {
10768 92 const_value = true;
10769 }
10770 }
10771
3/4
✓ Branch 0 taken 114 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 92 times.
✓ Branch 3 taken 22 times.
114 if (first_field && const_value)
10772 92 add_const_column(first_field);
10773
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 else if (second_field)
10774 22 add_equi_column(first_field, second_field);
10775 114 return;
10776 }
10777
2/2
✓ Branch 0 taken 463 times.
✓ Branch 1 taken 35 times.
498 if (is_cond_mult_equal(cond)) {
10778 463 auto equal = down_cast<Item_equal *>(cond);
10779
10780
2/2
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 328 times.
463 if (equal->get_const()) {
10781
5/8
✓ Branch 0 taken 135 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 135 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 270 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 135 times.
✓ Branch 7 taken 135 times.
270 for (Item_field &field : equal->get_fields()) {
10782
1/2
✓ Branch 0 taken 135 times.
✗ Branch 1 not taken.
135 add_const_column(field.field);
10783 }
10784 } else {
10785
1/2
✓ Branch 0 taken 328 times.
✗ Branch 1 not taken.
328 auto it = equal->get_fields().begin();
10786 328 Item_field& first_item = *it++;
10787
4/6
✓ Branch 0 taken 689 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 689 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 361 times.
✓ Branch 5 taken 328 times.
689 for (; it != equal->get_fields().end(); ++it) {
10788
1/2
✓ Branch 0 taken 361 times.
✗ Branch 1 not taken.
361 add_equi_column(first_item.field, it->field);
10789 }
10790 }
10791 }
10792 498 return;
10793 }
10794
10795 811 void Join_node::add_ordered_columns(const ORDER *order) {
10796
2/2
✓ Branch 0 taken 761 times.
✓ Branch 1 taken 811 times.
1572 for (; order; order = order->next) {
10797
2/2
✓ Branch 0 taken 757 times.
✓ Branch 1 taken 4 times.
761 if ((*order->item)->real_item()->type() == Item::FIELD_ITEM) {
10798 757 Field *field = ((Item_field *)(*order->item)->real_item())->field;
10799 /*
10800 If the field length is larger than the max_sort_length, then
10801 ORDER BY the field will not be guaranteed to be deterministic.
10802 */
10803
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 716 times.
757 if (field->field_length > max_sort_length) continue;
10804 716 Column_node *column = get_ordered_column_node(field);
10805 716 init_nodes.push_back(column);
10806 }
10807 }
10808 811 }
10809
10810 811 bool Join_node::is_ordered() const {
10811 811 List<Node> nodes(init_nodes);
10812
1/2
✓ Branch 0 taken 811 times.
✗ Branch 1 not taken.
811 List_iterator<Node> it(nodes);
10813 Node *node;
10814
10815
2/2
✓ Branch 0 taken 7926 times.
✓ Branch 1 taken 459 times.
8385 while ((node = it++)) {
10816 7926 node->todo--;
10817
2/2
✓ Branch 0 taken 7119 times.
✓ Branch 1 taken 807 times.
7926 if (node->todo == 0) {
10818
2/2
✓ Branch 0 taken 352 times.
✓ Branch 1 taken 6767 times.
7119 if (node == this) return true;
10819
1/2
✓ Branch 0 taken 6767 times.
✗ Branch 1 not taken.
6767 List_iterator<Node> pit(node->predecessors);
10820 Node *pnode;
10821
2/2
✓ Branch 0 taken 10022 times.
✓ Branch 1 taken 6767 times.
16789 while ((pnode = pit++)) {
10822
3/4
✓ Branch 0 taken 7250 times.
✓ Branch 1 taken 2772 times.
✓ Branch 2 taken 7250 times.
✗ Branch 3 not taken.
10022 if (pnode->todo) nodes.push_back(pnode);
10823 }
10824 }
10825 }
10826 459 return false;
10827 }
10828
10829 /*
10830 Test if the result order is deterministic for a JOIN table list.
10831
10832 @retval false not deterministic
10833 @retval true deterministic
10834 */
10835 682 bool is_order_deterministic(const mem_root_deque<TABLE_LIST *> *join_list,
10836 Item *cond, ORDER *order) {
10837 /*
10838 join_list->is_empty() means this is a UNION with a global LIMIT,
10839 always mark such statements as non-deterministic, although it
10840 might be deterministic for some cases (for example, UNION DISTINCT
10841 with ORDER BY a unique key of both side of the UNION).
10842 */
10843
3/4
✓ Branch 0 taken 682 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 681 times.
682 if (join_list->empty()) return false;
10844
10845
1/2
✓ Branch 0 taken 681 times.
✗ Branch 1 not taken.
681 Join_node root(join_list, cond, order);
10846
1/2
✓ Branch 0 taken 681 times.
✗ Branch 1 not taken.
681 return root.is_ordered();
10847 681 }
10848
10849 /*
10850 Test if the result order is deterministic for a single table.
10851
10852 @retval false not deterministic
10853 @retval true deterministic
10854 */
10855 138 bool is_order_deterministic(TABLE_LIST *table, Item *cond, ORDER *order) {
10856
4/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 103 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 27 times.
138 if (order == NULL && cond == NULL) return false;
10857
10858
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 Join_node root(table, cond, order);
10859
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 return root.is_ordered();
10860 130 }
10861
10862 /**
10863 Open and lock transactional system tables for read.
10864
10865 One must call close_trans_system_tables() to close systems tables opened
10866 with this call.
10867
10868 @param thd Thread context.
10869 @param table_list List of tables to open.
10870
10871 @note THR_LOCK deadlocks are not possible here because of the
10872 restrictions we put on opening and locking of system tables for writing.
10873 Thus, the system tables can be opened and locked for reading even if some
10874 other tables have already been opened and locked.
10875
10876 @note MDL-deadlocks are possible, but they are properly detected and
10877 reported.
10878
10879 @note Row-level deadlocks should be either avoided altogether using
10880 non-locking reads (as it is done now for InnoDB), or should be correctly
10881 detected and reported (in case of other transactional SE).
10882
10883 @note It is now technically possible to open non-transactional tables
10884 (MyISAM system tables) using this function. That situation might still happen
10885 if the user run the server on the elder data-directory or manually alters the
10886 system tables to reside in MyISAM instead of InnoDB. It will be forbidden in
10887 the future.
10888
10889 @return Error status.
10890 */
10891
10892 49459 bool open_trans_system_tables_for_read(THD *thd, TABLE_LIST *table_list) {
10893 uint counter;
10894 49459 uint flags = MYSQL_OPEN_IGNORE_FLUSH | MYSQL_LOCK_IGNORE_TIMEOUT;
10895
10896
1/2
✓ Branch 0 taken 49459 times.
✗ Branch 1 not taken.
49459 DBUG_TRACE;
10897
10898
2/4
✓ Branch 0 taken 49459 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 49459 times.
49459 assert(!thd->is_attachable_ro_transaction_active());
10899
10900 // Begin attachable transaction.
10901
10902
1/2
✓ Branch 0 taken 49459 times.
✗ Branch 1 not taken.
49459 thd->begin_attachable_ro_transaction();
10903
10904 // Open tables.
10905
10906
3/4
✓ Branch 0 taken 49459 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 49454 times.
49459 if (open_tables(thd, &table_list, &counter, flags)) {
10907
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 thd->end_attachable_transaction();
10908 5 return true;
10909 }
10910
10911 // Check the tables.
10912
10913
2/2
✓ Branch 0 taken 95842 times.
✓ Branch 1 taken 49454 times.
145296 for (TABLE_LIST *t = table_list; t; t = t->next_global) {
10914 // Ensure the t are in storage engines, which are compatible with the
10915 // attachable transaction requirements.
10916
10917
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 95842 times.
95842 if ((t->table->file->ha_table_flags() & HA_ATTACHABLE_TRX_COMPATIBLE) ==
10918 0) {
10919 // Crash in the debug build ...
10920 assert(!"HA_ATTACHABLE_TRX_COMPATIBLE is not set");
10921
10922 // ... or report an error in the release build.
10923 my_error(ER_UNKNOWN_ERROR, MYF(0));
10924 thd->end_attachable_transaction();
10925 return true;
10926 }
10927
10928 // The table should be in a transaction SE. This is not strict requirement
10929 // however. It will be make more strict in the future.
10930
10931
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 95840 times.
95842 if (!t->table->file->has_transactions())
10932
8/16
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
2 LogErr(WARNING_LEVEL, ER_SYSTEM_TABLE_NOT_TRANSACTIONAL,
10933 static_cast<int>(t->table_name_length), t->table_name);
10934 }
10935
10936 // Lock the tables.
10937
10938
3/4
✓ Branch 0 taken 49454 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 49453 times.
49454 if (lock_tables(thd, table_list, counter, flags)) {
10939
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 thd->end_attachable_transaction();
10940 1 return true;
10941 }
10942
10943 // Mark the table columns for use.
10944
10945
2/2
✓ Branch 0 taken 95838 times.
✓ Branch 1 taken 49453 times.
145291 for (TABLE_LIST *tables = table_list; tables; tables = tables->next_global)
10946
1/2
✓ Branch 0 taken 95838 times.
✗ Branch 1 not taken.
95838 tables->table->use_all_columns();
10947
10948 49453 return false;
10949 49459 }
10950
10951 /**
10952 Close transactional system tables, opened with
10953 open_trans_system_tables_for_read().
10954
10955 @param thd Thread context.
10956 */
10957
10958 49453 void close_trans_system_tables(THD *thd) { thd->end_attachable_transaction(); }
10959
10960 /**
10961 A helper function to close a mysql.* table opened
10962 in an auxiliary THD during bootstrap or in the main
10963 connection, when we know that there are no locks
10964 held by the connection due to a preceding implicit
10965 commit.
10966
10967 This function assumes that there is no
10968 statement transaction started for the operation
10969 itself, since mysql.* tables are not transactional
10970 and when they are used the binlog is off (DDL
10971 binlogging is always statement-based.
10972
10973 We need this function since we'd like to not
10974 just close the system table, but also release
10975 the metadata lock on it.
10976
10977 Note, that in LOCK TABLES mode this function
10978 does not release the metadata lock. But in this
10979 mode the table can be opened only if it is locked
10980 explicitly with LOCK TABLES.
10981 */
10982
10983 139952 void close_mysql_tables(THD *thd) {
10984 /* No need to commit/rollback statement transaction, it's not started. */
10985
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 139969 times.
139952 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT));
10986 139969 close_thread_tables(thd);
10987 139975 thd->mdl_context.release_transactional_locks();
10988 139979 }
10989
10990 /**
10991 Open a log table.
10992 Opening such tables is performed internally in the server
10993 implementation, and is a 'nested' open, since some tables
10994 might be already opened by the current thread.
10995 The thread context before this call is saved, and is restored
10996 when calling close_log_table().
10997 @param thd The current thread
10998 @param one_table Log table to open
10999 @param [out] backup Temporary storage used to save the thread context
11000 */
11001 38839 TABLE *open_log_table(THD *thd, TABLE_LIST *one_table,
11002 Open_tables_backup *backup) {
11003 38839 uint flags = (MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK |
11004 MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY | MYSQL_OPEN_IGNORE_FLUSH |
11005 MYSQL_LOCK_IGNORE_TIMEOUT | MYSQL_LOCK_LOG_TABLE);
11006 TABLE *table;
11007
1/2
✓ Branch 0 taken 38839 times.
✗ Branch 1 not taken.
38839 DBUG_TRACE;
11008
11009
1/2
✓ Branch 0 taken 38839 times.
✗ Branch 1 not taken.
38839 thd->reset_n_backup_open_tables_state(backup,
11010 Open_tables_state::SYSTEM_TABLES);
11011
11012
3/4
✓ Branch 0 taken 38839 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38835 times.
✓ Branch 3 taken 4 times.
38839 if ((table = open_ltable(thd, one_table, one_table->lock_descriptor().type,
11013 flags))) {
11014
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38835 times.
38835 assert(table->s->table_category == TABLE_CATEGORY_LOG);
11015 /* Make sure all columns get assigned to a default value */
11016
1/2
✓ Branch 0 taken 38835 times.
✗ Branch 1 not taken.
38835 table->use_all_columns();
11017
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38835 times.
38835 assert(table->no_replicate);
11018 } else
11019
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 thd->restore_backup_open_tables_state(backup);
11020
11021 38839 return table;
11022 38839 }
11023
11024 /**
11025 Close a log table.
11026 The last table opened by open_log_table()
11027 is closed, then the thread context is restored.
11028 @param thd The current thread
11029 @param backup The context to restore.
11030 */
11031 38835 void close_log_table(THD *thd, Open_tables_backup *backup) {
11032
1/2
✓ Branch 0 taken 38835 times.
✗ Branch 1 not taken.
38835 Query_tables_list query_tables_list_backup;
11033
11034 /*
11035 In order not affect execution of current statement we have to
11036 backup/reset/restore Query_tables_list part of LEX, which is
11037 accessed and updated in the process of closing tables.
11038 */
11039
1/2
✓ Branch 0 taken 38835 times.
✗ Branch 1 not taken.
38835 thd->lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
11040
1/2
✓ Branch 0 taken 38835 times.
✗ Branch 1 not taken.
38835 close_thread_tables(thd);
11041
1/2
✓ Branch 0 taken 38835 times.
✗ Branch 1 not taken.
38835 thd->lex->restore_backup_query_tables_list(&query_tables_list_backup);
11042
1/2
✓ Branch 0 taken 38835 times.
✗ Branch 1 not taken.
38835 thd->restore_backup_open_tables_state(backup);
11043 38835 }
11044
11045 /**
11046 @} (end of group Data_Dictionary)
11047 */
11048